Skip to content

Support public error serialization and useful HTTP failures - #13

Merged
jmorrell merged 1 commit into
mainfrom
fix/public-error-boundaries
Oct 15, 2026
Merged

jmorrell merged 1 commit into
mainfrom
fix/public-error-boundaries

Conversation

@jmorrell

Copy link
Copy Markdown
Owner

Applications currently have to catch every service failure themselves to prevent internal error details from reaching callers. HTTP failures can also produce an empty RpcError.message or discard a server's useful upload-limit explanation.

Add an optional synchronous serializeError(error, method) callback that selects the public JSON-RPC error while onError retains the original failure for diagnostics. Carry it through HTTP handlers, raw sessions, and both WebSocket peers. Existing serialization remains unchanged when the option is omitted, and protocol errors retain their standard responses.

For non-2xx HTTP responses, preserve an explicitly supplied JSON { error: string } explanation. Other responses use Request failed (HTTP <status>). instead of relying on status text or displaying arbitrary response bodies. The error code remains the HTTP status. Documentation describes these conventions and makes clear that a failed response does not establish whether execution occurred.

Upstreams the reusable parts of https://github.com/jmorrell/stacks/pull/263 and https://github.com/jmorrell/stacks/pull/264. Application-specific error classifications, telemetry, and UI recovery stay in Stacks.

Validation: all 171 tests passed, including Workers runtime coverage for serialization in both WebSocket directions, mixed HTTP batch outcomes with original diagnostics, and HTTP explanation/fallback behavior. Formatting checks and build passed. Lint passed with three pre-existing unused-import warnings in the unchanged websocket.test.ts. Author review traced option propagation through all public transport entry points and checked default-error compatibility; no independent review was performed in this repository.

Types and sequencing: RpcHandlerOptions gains the optional serializer; RpcSessionOptions includes those handler options; the WebSocket client accepts RpcHandlerOptions directly instead of its private onError-only alias. Wire response types are unchanged. On a handler failure, the existing onError callback runs before the optional serializer. Both callbacks must not throw.

@jmorrell
jmorrell merged commit 9948f5e into main Oct 15, 2026
1 check passed
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