298. Ручная отчётность об ошибках в main
Добавление полезной отчётности об ошибках эмуляции в main_only_background.py.
Урок 298 из 356 · tests/chapter_08_manual_main/test_298_manual_main_error_reporting.py
Файл для обновления
main_only_background.pyЗачем нужен этот шаг
main_only_background.py выполняет реальный ручной цикл ROM с pygame. Когда реальное выполнение ROM сталкивается с отсутствующим поведением эмулятора, пользователю нужен контекст до трассировки Python.
Без контекста ошибка может выглядеть просто как
ValueError: Unsupported CPU bus read: 4020С контекстом main_only_background.py также должен выводить полезное состояние эмулятора:
Emulation Error:
type=ValueError
message=Unsupported CPU bus read: 4020
pc=$812A
ppu_frame=123
ppu_scanline=241
ppu_cycle=10Это не заменяет трассировку. Исходное исключение по-прежнему должно быть повторно возбуждено, чтобы разработчики могли отлаживать как обычно.
Пример предполагаемой реализации
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()Почему KeyboardInterrupt перехватывается отдельно? Ctrl+C — это намеренная остановка пользователем, а не сбой эмулятора. Должно выводиться дружелюбное сообщение об остановке, а не отчёт об ошибке эмуляции.
Почему неожиданные исключения повторно возбуждаются? Отчёт об ошибке даёт контекст эмулятора, но трассировка всё равно важна. Повторное возбуждение сохраняет исходный сбой видимым для отладки.
Вне рамок этого шага
- изменение диагностики опкодов CPU
- перехват и скрытие всех ошибок
- запись логов в файлы
- вызов main() из pytest
Запустить этот урок
uv run pytest tests/chapter_08_manual_main/test_298_manual_main_error_reporting.py -v