298. Manual main error reporting
Add useful emulation error reporting to main_only_background.py.
Lesson 298 of 356 · tests/chapter_08_manual_main/test_298_manual_main_error_reporting.py
File to update
main_only_background.pyWhy this step exists
main_only_background.py runs a real manual ROM loop with pygame. When real ROM execution hits a missing emulator behavior, the user needs context before the Python traceback.
Without context, an error may only say
ValueError: Unsupported CPU bus read: 4020With context, main_only_background.py should also print useful emulator state:
Emulation Error:
type=ValueError
message=Unsupported CPU bus read: 4020
pc=$812A
ppu_frame=123
ppu_scanline=241
ppu_cycle=10This does not replace the traceback. The original exception should still be re-raised so developers can debug normally.
Suggested implementation example
def print_emulation_error(error: Exception, console: Console) -> None:
print("Emulation Error:")
print(f" type={type(error).__name__}")
print(f" message={error}")
print(f" pc=${console.cpu.pc:04X}")
print(f" ppu_frame={console.ppu.frame}")
print(f" ppu_scanline={console.ppu.scanline}")
print(f" ppu_cycle={console.ppu.cycle}")
def main() -> None:
...
pygame.init()
try:
window = pygame.display.set_mode(...)
running = True
while running:
...
executed = console.step_until_next_frame()
framebuffer = console.render_background_framebuffer()
draw_framebuffer(window, framebuffer, SCALE)
pygame.display.flip()
except KeyboardInterrupt:
print("Stopped by user.")
except Exception as error:
print_emulation_error(error, console)
raise
finally:
pygame.quit()Why catch KeyboardInterrupt separately? Ctrl+C is an intentional user stop, not an emulator failure. It should print a friendly stop message and should not print an emulation error report.
Why re-raise unexpected exceptions? The error report gives emulator context, but the traceback still matters. Re-raise keeps the original failure visible for debugging.
Out of scope
- changing CPU opcode diagnostics
- catching and hiding all errors
- writing logs to files
- calling main() from pytest
Run this lesson
uv run pytest tests/chapter_08_manual_main/test_298_manual_main_error_reporting.py -v