From 78bf32b8fbafc529915c8fefcfedbc820064c215 Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Fri, 10 Jul 2026 19:13:21 +0100 Subject: [PATCH] better error for corrup file --- neo/rawio/axonrawio.py | 18 +++++++++++++++--- neo/test/rawiotest/test_axonrawio.py | 15 +++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/neo/rawio/axonrawio.py b/neo/rawio/axonrawio.py index 75457ce57..7d348a48b 100644 --- a/neo/rawio/axonrawio.py +++ b/neo/rawio/axonrawio.py @@ -490,8 +490,13 @@ def parse_axon_soup(filename): Returns ------- - dict or None - Header dictionary with file metadata, or None if file signature is invalid + dict + Header dictionary with file metadata. + + Raises + ------ + NeoReadWriteError + If the file does not start with a valid ABF signature (b"ABF " or b"ABF2"). """ with open(filename, "rb") as fid: f = StructFile(fid) @@ -502,7 +507,14 @@ def parse_axon_soup(filename): elif signature == b"ABF2": return _parse_abf_v2(f, headerDescriptionV2) else: - return None + # The first 4 bytes are the ABF magic; anything else means the file is not an ABF + # file, is corrupt, or is an unsupported variant. Raise here rather than returning + # None so the caller gets a clear error instead of a downstream NoneType access. + raise NeoReadWriteError( + f"Could not parse {filename} as an ABF file: expected the header to start with " + f"signature b'ABF ' or b'ABF2', but found {signature}. The file is not an ABF " + f"file, is corrupt, or is an unsupported variant." + ) def _parse_abf_v1(f, header_description): diff --git a/neo/test/rawiotest/test_axonrawio.py b/neo/test/rawiotest/test_axonrawio.py index cb1f07a6f..fb98eb07b 100644 --- a/neo/test/rawiotest/test_axonrawio.py +++ b/neo/test/rawiotest/test_axonrawio.py @@ -2,6 +2,7 @@ import unittest from neo.rawio.axonrawio import AxonRawIO, parse_axon_soup +from neo.core import NeoReadWriteError from neo.test.rawiotest.common_rawio_test import BaseTestRawIO @@ -29,6 +30,20 @@ def test_read_raw_protocol(self): reader.read_raw_protocol() + def test_unparseable_file_raises(self): + # A file whose header does not start with a valid ABF signature must raise a clear error + # rather than a cryptic NoneType error deep in parsing. The fixture has a zeroed signature. + path = self.get_local_path("axon/intracellular_data/files_with_errors/unparseable_header.abf") + expected_msg = ( + f"Could not parse {path} as an ABF file: expected the header to start with signature " + f"b'ABF ' or b'ABF2', but found b'\\x00\\x00\\x00\\x00'. The file is not an ABF file, " + f"is corrupt, or is an unsupported variant." + ) + reader = AxonRawIO(filename=path) + with self.assertRaises(NeoReadWriteError) as cm: + reader.parse_header() + self.assertEqual(str(cm.exception), expected_msg) + def test_v1_reads_real_acquisition_date(self): # ABF1 stores the calendar date in lFileStartDate (a YYYYMMDD-packed integer). Older neo # ignored that field and hardcoded 1900-01-01, so the recording date was always wrong for