fix(host-service): surface breaking failures instead of swallowing them

Merged
KI
4mo ago
+59-13

Problem

Breaking host-service failures never reached the user. The confirmed 1.12.0 crash is the canonical case: a migration fails, the failure is swallowed, and the service limps on a half-migrated DB — then fails later in a confusing, unrelated way. Failures were being swallowed at multiple layers with no loud surface.

What changed

Three targeted fixes, each un-swallowing a breaking failure (legitimate best-effort catches — teardown, fan-out guards, optional features — were deliberately left alone):

  1. db.ts — migration throws. Removed the try/catch that logged-and-continued around migrate(), so a failed migration crashes the child at startup (before the safety net is installed → main().catch → exit(1)) with the real stack, instead of returning a half-migrated DB. Also added busy_timeout = 5000.

  2. host-service-coordinator.ts — alert on child crash. When a running child dies unexpectedly, the coordinator now shows a native dialog ("Host service crashed" with exit code/signal) and a Restart button, rather than only emitting a passive stopped status event nothing reacts to. Deliberate stop()/quit set status to stopped first, so they return early and never alert; startup-phase deaths are surfaced by (3), so no double-alert.

  3. LocalHostServiceProvider.tsx — surface start failures. The fire-and-forget start mutation now has an onError that logs + toasts the failure instead of dropping the rejection into unread React Query state (auth-token preconditions filtered to avoid startup-race noise).

Deliberately out of scope

  • Not moving host-service in-process (keeps crash isolation / clean reset() / per-org separation).
  • Not changing the process safety net to exit() on every uncaught error — crashing the whole session-supervisor on a stray post-startup throw, with no auto-restart, is worse than logging it.

Verification

  • Typecheck (desktop + host-service): clean. Lint: clean. host-service createDb tests pass.
  • The native crash dialog fires only on a real child crash; not yet driven end-to-end in the running app.

Open in Stage

Summary by cubic

Stop swallowing breaking host-service failures and surface them clearly to users. Failed migrations now crash early, crashes show a native error dialog, and start errors show a toast.

  • Bug Fixes
    • packages/host-service/src/db/db.ts: Let failed migrations throw instead of returning a half‑migrated DB; set busy_timeout = 5000.
    • apps/desktop/src/main/lib/host-service-coordinator.ts: Show a native “Host service crashed” error box with exit code/signal on unexpected exits; emit the real previous status; alert only for crashes of running children; recovery via tray menu Restart.
    • apps/desktop/src/renderer/.../LocalHostServiceProvider.tsx: Add onError to the start mutation to log and toast failures; ignore typed UNAUTHORIZED auth‑token preconditions.
    • apps/desktop/src/lib/trpc/routers/host-service-coordinator: Throw TRPCError with code UNAUTHORIZED when no auth token is present so the renderer can reliably filter expected preconditions.

Summary by CodeRabbit

  • New Features
    • Added a native error dialog when the host service stops unexpectedly, informing users that workspaces/terminals are unavailable until restart.
    • Added clearer UI feedback when the host service fails to start (toast notification on other errors).
  • Bug Fixes
    • Improved detection and handling of unexpected host-service exits, keeping availability/status consistent.
    • Improved unauthorized-start behavior by suppressing start error notifications when the user isn’t authenticated.
  • Bug Fixes / Reliability
    • Improved database startup reliability with a SQLite busy timeout and safer migration behavior to avoid half-migrated states.