Skip to content

Keep editor alive when game code throws an exception - #138

Open
mblackman wants to merge 1 commit into
mainfrom
editor-game-exception-guard
Open

Keep editor alive when game code throws an exception#138
mblackman wants to merge 1 commit into
mainfrom
editor-game-exception-guard

Conversation

@mblackman

Copy link
Copy Markdown
Owner

Problem

The editor runs the project in-process (editor mode is the same Game instance with isPaused-gated systems). An uncaught exception from game or Lua code propagated up through FrameLoopGame::Run's loop and crashed the whole editor. (The separate Run Player button already isolates crashes via a child process — that path was never affected.)

Change

New header-only RunEditorGuarded(GameConfig&, context, fn) in src/Engine/EditorExceptionGuard.h:

  • In editor mode: catches std::exception (and ...), logs it via Logger::Error (surfaces in the editor Console panel), and sets isPaused = true — so the editor stays alive and the throwing tick doesn't re-raise every frame. Fix the script, hit Play again.
  • Outside editor mode (standalone player, headless bench/bake/CI): passthrough — exceptions propagate unchanged, no try/catch overhead beyond one bool check.

Applied at the three seams where game code executes during an editor session:

  1. FrameLoop::Update — the per-frame tick (registry_->Update), which runs every system including Lua.
  2. FrameLoop::ProcessInput — the key/mouse/wheel EmitEvent dispatches (Lua input handlers, UIButtonSystem callbacks).
  3. EditorToolbarPanel Play/Stop — ReloadScene/StopScene, which run during ImGui render outside the Update guard. A broken scene load on Play was a real editor-crash path; Play now only un-pauses if the reload succeeded.

Lua runtime errors inside a script's update were already swallowed by ScriptSystem's protected_function. This covers the harder failures: C++ exceptions from systems/bindings, and scene loads / input callbacks invoked outside a protected boundary.

Verification

  • cmake --build build/editor-debug — clean.
  • clang-format 18.1.8 — passes on all three files.

The editor runs the project in-process, so an uncaught exception from game
or Lua code propagated up through the frame loop and crashed the whole
editor. Add RunEditorGuarded, which in an editor session catches the
exception, logs it to the console, and pauses execution instead of letting
it escape; outside editor mode it is a passthrough so the player and
headless tooling fail exactly as before.

Applied at the seams where game code runs during an editor session: the
per-frame Update tick, the input-event dispatches (Lua handlers and UI
button callbacks), and the toolbar Play/Stop scene operations, which run
during ImGui render outside the Update guard.
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.

1 participant