feat: improve spawn error handling and reporting across full stack (#249)

* feat: improve spawn error handling and reporting across full stack

- Return error result instead of throwing in apiMachine spawn handler
- Add lastSpawnError field to RunnerState for persistent error tracking
- Add error awaiter system for early process exit/error detection before webhook
- Build detailed webhook failure messages with exit code, signal, and stderr tail
- Report spawn outcomes to hub via runner state updates
- Handle more spawn result types in rpcGateway with better error messages
- Display runner last spawn error in web UI (NewSession & SpawnSession)
- Extract shared formatRunnerSpawnError utility to avoid duplication

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cli): narrow spawnResult type check to fix TS2339 error

Use `type === 'error'` instead of `type !== 'success'` to properly
narrow the discriminated union, allowing TypeScript to infer errorMessage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
fireblue
2026-03-09 20:55:50 +08:00
committed by GitHub
co-authored by Claude Opus 4.6
parent b4b73d4405
commit 4716d315b7
8 changed files with 234 additions and 7 deletions
+15
View File
@@ -0,0 +1,15 @@
import type { Machine } from '../types/api'
export function formatRunnerSpawnError(machine: Machine | null): string | null {
const lastSpawnError = machine?.runnerState?.lastSpawnError
if (!lastSpawnError?.message) {
return null
}
const at = typeof lastSpawnError.at === 'number'
? new Date(lastSpawnError.at).toLocaleString()
: null
return at
? `${lastSpawnError.message} (${at})`
: lastSpawnError.message
}