Skip to content

Support presenting fatal errors with a native message box #454

Description

@botoddly

Problem

Pixely cannot present a message to the player outside the render pipeline. Every diagnostic path ends at an exception or stderr. A windowed game started from a shortcut or a packaged build has no attached console, so an unhandled exception terminates the process with no visible explanation — the window simply disappears.

This matters most where the failure also removes the ability to render an error:

  • PixelyFactory initialization failures throw before a window exists.
  • During a stage transition, a throwing ServiceProvider.Dispose or configure callback propagates out of StageManager.ApplyPendingTransition and out of PixelyApp.Run, which has no exception handling. The outgoing stage is already partially torn down, so no view or renderer remains to report anything.
  • Any other exception escaping Run.

SDL3 supports message boxes and the binding already exposes SDL_ShowSimpleMessageBox and SDL_ShowMessageBox, but Pixely does not surface them. Window already wraps comparable native modal UI (ShowModalOpenFileDialog, ShowModalSaveFileDialog), so there is an established place for this.

Expected behavior

  • A message box can be shown with a severity, title, and message, and blocks until it is dismissed.
  • It is parented to a Window when one exists, matching the existing modal dialog methods.
  • It can also be shown without a window, so it works before window creation and after teardown.
  • Failure to present the box never replaces or masks the error being reported.

Possible API

An instance method on Window mirroring the file dialogs, plus a windowless entry point for the cases where no window exists.

public enum MessageBoxSeverity
{
    Information,
    Warning,
    Error
}
// Window
public void ShowModalMessageBox(MessageBoxSeverity severity, string title, string message);
public static class MessageBox
{
    public static void Show(MessageBoxSeverity severity, string title, string message);
}

The multi-button SDL_ShowMessageBox form is out of scope. The simple form covers reporting; a choice-returning overload can be added later if a caller needs one.

Open questions

  • Should PixelyApp.Run install a top-level handler that presents the box and terminates, or should this stay opt-in and left to the application's Main? Automatic reporting changes existing failure behavior, and it must still write the exception to stderr rather than reducing it to a dialog string.
  • Should the windowless entry point be static, or resolved from the container? Static works before the provider exists, which is one of the motivating cases.

Coverage

Automated coverage is limited, since presentation cannot be asserted in headless CI:

  • severity maps to the corresponding SDL_MessageBoxFlags value;
  • argument validation for title and message;
  • a request made with no window and no display available reports the failure without throwing over the original error;
  • existing window modal dialog behavior is unchanged.

Presentation itself is verified through a tutorial covering both the parented and windowless paths.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions