Skip to content

fix(core): stop leaking backend exception details in RPC errors#231

Open
pranavosu wants to merge 1 commit into
mainfrom
fix/rpc-error-leak-227
Open

fix(core): stop leaking backend exception details in RPC errors#231
pranavosu wants to merge 1 commit into
mainfrom
fix/rpc-error-leak-227

Conversation

@pranavosu

Copy link
Copy Markdown
Contributor

Summary

errorResponseFromCatch in packages/core/src/rpc.ts forwarded error.message verbatim and copied error.name onto the wire for any error whose name wasn't literally Error. Non-ApiError throws — the common case for driver/SDK failures (Postgres, DynamoDB, etc.) — therefore returned a JSON-RPC error whose message was the raw driver message and whose data.name was the raw exception class name. That leaks internal implementation details to any caller and produces unstable, non-actionable error shapes.

Fixes #227.

Change

errorResponseFromCatch now treats ApiError as the only deliberate, wire-safe error shape:

  • ApiError passes through verbatim: HTTP status becomes the code, plus message, the BB-level name (omitted when it's the default ApiError), and retriable.
  • Everything else (driver/SDK exceptions, unexpected bugs) collapses to a generic 500 / "Internal error" with no data — no raw class name, no raw message.

The full error is still logged server-side by both callers (lambda-handler.ts console.error, dev-server.ts [rpc-err] log + stack), so debuggability is unchanged.

This aligns the implementation with the documented D-003 safety net: "Unhandled errors (plain Error with no custom .name) still serialize as generic 500s with no name."

Testing

  • Added unit tests in packages/core/src/rpc.test.ts covering: a simulated driver exception (custom class name + secret-bearing message) collapsing to 500/Internal error with no leaked strings, plain Error and non-Error throws collapsing likewise, and ApiError passing through verbatim with status/message/name/retriable (including the default-name omission).
  • npm run build and the rpc.test.js suite pass (12/12). Biome lint clean on the changed files.

Note: the ApiError wire contract is unchanged; only previously-unstable non-ApiError shapes change, so this is a patch.

…ResponseFromCatch forwarded error.message verbatim and copied error.name for any error whose name wasn't literally 'Error', so raw Postgres/DynamoDB driver exception class names and messages reached clients over the wire. Only ApiError is a deliberate wire-safe shape, so it now passes through verbatim (status, message, BB name, retriable) while every other throw collapses to a generic 500 / 'Internal error'. Callers already log the full error server-side. Aligns the implementation with the D-003 safety net (unhandled errors serialize as generic 500s with no name). Fixes #227
@pranavosu
pranavosu requested a review from a team as a code owner July 17, 2026 20:59
@changeset-bot

changeset-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 43a1d96

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@aws-blocks/core Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

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.

RPC handler leaks raw backend exception class names and messages to clients

1 participant