298. Informe manual de errores en main

Añadir un informe de errores de emulación útil a main_only_background.py.

Lección 298 de 356 · tests/chapter_08_manual_main/test_298_manual_main_error_reporting.py

Archivo a actualizar

main_only_background.py

Por qué existe este paso

main_only_background.py ejecuta un bucle de ROM manual real con pygame. Cuando la ejecución real de la ROM encuentra un comportamiento del emulador que falta, el usuario necesita contexto antes del traceback de Python.

Sin contexto, un error puede decir solo

ValueError: Unsupported CPU bus read: 4020

Con contexto, main_only_background.py también debe imprimir información útil del estado del emulador:

Emulation Error:
    type=ValueError
    message=Unsupported CPU bus read: 4020
    pc=$812A
    ppu_frame=123
    ppu_scanline=241
    ppu_cycle=10

Esto no sustituye al traceback. La excepción original debe seguir relanzándose para que los desarrolladores puedan depurar con normalidad.

Ejemplo de implementación sugerido

def print_emulation_error(error: Exception, console: Console) -> None:
    print("

Error de emulación:")

    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("

Detenido por el usuario.")

    except Exception as error:
        print_emulation_error(error, console)
        raise
    finally:
        pygame.quit()

¿Por qué capturar KeyboardInterrupt por separado? Ctrl+C es una detención intencionada del usuario, no un fallo del emulador. Debe imprimir un mensaje de detención amistoso y no debe imprimir un informe de error de emulación.

¿Por qué relanzar las excepciones inesperadas? El informe de error aporta contexto del emulador, pero el traceback sigue siendo importante. Relanzarlo mantiene visible el fallo original para depurar.

Fuera de alcance

  • Cambiar los diagnósticos de opcodes de la CPU
  • Capturar y ocultar todos los errores
  • Escribir registros en archivos
  • Llamar a main() desde pytest

Ejecutar esta lección

uv run pytest tests/chapter_08_manual_main/test_298_manual_main_error_reporting.py -v