feat: Exit on first Python callback exception (closes #133)
By default, McRogueFace now exits with code 1 on the first unhandled exception in timer, click, key, or animation callbacks. This prevents repeated exception output that wastes resources in AI-driven development. Changes: - Add exit_on_exception config flag (default: true) - Add --continue-after-exceptions CLI flag to preserve old behavior - Update exception handlers in Timer, PyCallable, and Animation - Signal game loop via McRFPy_API atomic flags - Return proper exit code from main() Before: Timer exceptions repeated 1000+ times until timeout After: Single traceback, clean exit with code 1 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
9028bf485e
commit
19ded088b0
12 changed files with 160 additions and 8 deletions
|
|
@ -27,6 +27,9 @@ std::shared_ptr<PyFont> McRFPy_API::default_font;
|
|||
std::shared_ptr<PyTexture> McRFPy_API::default_texture;
|
||||
PyObject* McRFPy_API::mcrf_module;
|
||||
|
||||
// Exception handling state
|
||||
std::atomic<bool> McRFPy_API::exception_occurred{false};
|
||||
std::atomic<int> McRFPy_API::exit_code{0};
|
||||
|
||||
static PyMethodDef mcrfpyMethods[] = {
|
||||
|
||||
|
|
@ -1144,6 +1147,23 @@ PyObject* McRFPy_API::_getMetrics(PyObject* self, PyObject* args) {
|
|||
// Add general metrics
|
||||
PyDict_SetItemString(dict, "current_frame", PyLong_FromLong(game->getFrame()));
|
||||
PyDict_SetItemString(dict, "runtime", PyFloat_FromDouble(game->runtime.getElapsedTime().asSeconds()));
|
||||
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
// Exception handling implementation
|
||||
void McRFPy_API::signalPythonException() {
|
||||
// Check if we should exit on exception (consult config via game)
|
||||
if (game && !game->isHeadless()) {
|
||||
// In windowed mode, respect the config setting
|
||||
// Access config through game engine - but we need to check the config
|
||||
}
|
||||
|
||||
// For now, always signal - the game loop will check the config
|
||||
exception_occurred.store(true);
|
||||
exit_code.store(1);
|
||||
}
|
||||
|
||||
bool McRFPy_API::shouldExit() {
|
||||
return exception_occurred.load();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue