Skip to content

Preserve real parse diagnostics instead of the generic section wrapper - #18

Merged
ctoth merged 1 commit into
masterfrom
fix/error-diagnostics-issue-12
Jul 27, 2026
Merged

Preserve real parse diagnostics instead of the generic section wrapper#18
ctoth merged 1 commit into
masterfrom
fix/error-diagnostics-issue-12

Conversation

@ctoth

@ctoth ctoth commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Fixes #12.

The problem

Both generic section loops caught everything and replaced it with one message:

except Exception:
    self.parse_fail("Error reading section %r" % section_name)

That discarded the precise ParseError an inner reader had already raised, and it
laundered real internal bugs into what looked like a file-format complaint.

The fix

  • Both section loops (AreaFile.load_sections, the Smaug/SWR loop) re-raise
    ParseError untouched, and include repr(error) when wrapping anything else, so an
    internal error is still identifiable as one.
  • load_smaug_vnum_section / load_swr_vnum_section slice instead of index when
    peeking at the character after # (self.data[self.index + 1:self.index + 2]), so a
    file ending in # ends the section rather than raising IndexError.
  • CircleAreaFile.read_record_header raises a located ParseError on a non-numeric
    record header instead of letting int() escape a bare ValueError.

No new abstraction; three small edits plus a test file.

Verification

test_error_reporting.py (6 tests) covers all four behaviours. With the source change
stashed, all six fail:

FAILED test_error_reporting.py::test_rom_section_error_keeps_the_specific_parse_message
FAILED test_error_reporting.py::test_smaug_section_error_keeps_the_specific_parse_message
FAILED test_error_reporting.py::test_non_parse_errors_are_reported_with_the_original_error
FAILED test_error_reporting.py::test_vnum_section_tolerates_a_trailing_hash_at_end_of_file[SmaugAreaFile]
FAILED test_error_reporting.py::test_vnum_section_tolerates_a_trailing_hash_at_end_of_file[SwrAreaFile]
FAILED test_error_reporting.py::test_circle_record_header_rejects_a_non_numeric_vnum
6 failed in 1.89s

With the fix: 6 passed in 0.77s. Full suite: 950 passed in 94.76s.

End-to-end, exercising what a CLI would actually print via str(e):

=== case 1: unterminated mob string, what a CLI prints via str(e) ===
   ...\repro.are line 5 col 0 in section mobiles: Unterminated string
=== case 2: SMAUG/SWR file ending in '#' ===
   SmaugAreaFile: parsed cleanly, mobs=OrderedDict()
   SwrAreaFile: parsed cleanly, mobs=OrderedDict()
=== case 3: Circle bare '#' record header ===
   ParseError : ...\broken.wld line 1 col -1: Expected numeric record header, got ''
=== control: a genuine internal error still surfaces its own text ===
   ...\repro.are line 1 col -1 in section mobiles: Error reading section 'mobiles': RuntimeError('internal boom')
=== control: a real area file still parses ===
   test/rom\air.are: 2 mobs 40 rooms 1 objects
   test/rom\arachnos.are: 19 mobs 56 rooms 4 objects
   test/rom\astral.are: 20 mobs 80 rooms 26 objects

ruff check on area_reader/__init__.py reports the same 153 pre-existing errors before
and after; the new test file is clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PQh6Vypbkqk4vnqPUE8yTY

Fixes #12.

The two generic section loops caught every exception and replaced it with
"Error reading section %r", so a precise ParseError raised deep in a reader
("Unterminated string") was invisible to anyone showing str(e), and genuine
internal bugs were laundered into what looked like a file-format complaint.

- Both section loops now re-raise ParseError untouched, and include repr() of
  any other exception when wrapping it, so an internal error is still
  identifiable as one.
- load_smaug_vnum_section / load_swr_vnum_section sliced instead of indexed
  when peeking at the character after '#', so a file ending in '#' ends the
  section instead of raising IndexError.
- CircleAreaFile.read_record_header raises a located ParseError on a
  non-numeric record header instead of letting int() raise a bare ValueError.

test_error_reporting.py covers all four behaviours; all six tests fail on the
previous code.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PQh6Vypbkqk4vnqPUE8yTY
@ctoth
ctoth merged commit 3a25768 into master Jul 27, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generic 'Error reading section' wrapper hides the real diagnostic and launders internal IndexError/ValueError

1 participant