Problem
When user presses Esc during a running session, several error handling gaps cause:
- Stack traces shown in UI instead of silent cancellation
- Potential process crash from unhandled rejection
- Session stuck state if hackbrowser cleanup throws
- Double error messages (cancel + provider error)
Fixes
1. Guard stopHackbrowser in cancel — c1b9831
If hackbrowser worker died, handle.send() throws, rest of cancel() skipped, session permanently stuck. Wrapped in try-catch.
2. Catch prompt_async rejection — 53b6f47
Fire-and-forget prompt with no .catch() causes unhandled rejection and process crash in Bun. Added .catch(() => {}).
3. Suppress cancel on sync prompt endpoint — f112e33
Same pattern as loop() fix (8aa8db8) — cancel error caught silently.
4. Skip error publishing on abort — 8e0914c
AI SDK AbortError entered catch block and published as provider error to frontend causing double error. Now checks abort.aborted first and breaks silently.
Not Fixing (by design)
- IngestQueue zombie tasks — Esc cancels only active task, queue continues. Intentional — qpause exists for stopping the queue.
- Double cancel call — defer cancel second call is harmless no-op.
- CancelledError class — string comparison works, typed error refactor deferred.
- defer+resolve+cancel race — theoretical, practically impossible timing.
Problem
When user presses Esc during a running session, several error handling gaps cause:
Fixes
1. Guard stopHackbrowser in cancel — c1b9831
If hackbrowser worker died, handle.send() throws, rest of cancel() skipped, session permanently stuck. Wrapped in try-catch.
2. Catch prompt_async rejection — 53b6f47
Fire-and-forget prompt with no .catch() causes unhandled rejection and process crash in Bun. Added .catch(() => {}).
3. Suppress cancel on sync prompt endpoint — f112e33
Same pattern as loop() fix (8aa8db8) — cancel error caught silently.
4. Skip error publishing on abort — 8e0914c
AI SDK AbortError entered catch block and published as provider error to frontend causing double error. Now checks abort.aborted first and breaks silently.
Not Fixing (by design)