Skip to content

fix: raise invoke errors in the typedErrors pipeline function - #390

Merged
hoegertn merged 2 commits into
mainfrom
fix/appsync-typed-errors-pipeline
Oct 29, 2026
Merged

hoegertn merged 2 commits into
mainfrom
fix/appsync-typed-errors-pipeline

Conversation

@hoegertn

Copy link
Copy Markdown
Contributor

With typedErrors: true, an untyped error thrown by a resolver handler was
silently swallowed. createAppSyncHandler rethrows untyped errors, so the
Lambda invocation fails and AppSync puts the failure into the pipeline
function's ctx.error. The function's response handler returned
ctx.result without raising it, so AppSync dropped the error and the field
resolved to null with no GraphQL error and HTTP 200. Clients could not
tell a failed mutation from an empty result.

The resolver-level if (ctx.error) util.appendError(...) branch could not
catch this: an error left in a pipeline function's ctx.error never
reaches the resolver's ctx.error. Typed errors (the __appSyncError
envelope) were not affected.

Changes:

  • The pipeline function now calls util.error(ctx.error.message, ctx.error.type),
    which reports the same message and Lambda:Unhandled type a UNIT
    direct-Lambda resolver does.
  • Remove the dead ctx.error branch from the resolver response handler.
  • Correct the typedErrors prop doc and llm.md: without the flag the
    Lambda gets no APPSYNC_TYPED_ERRORS, so typed errors rethrow and surface
    as Lambda:Unhandled, not as envelope field data.
  • Add tests that execute the synthesized inline handlers with a fake
    util, covering invoke errors, typed envelopes and pass-through results.
    The invoke-error test fails against the previous handler.

Verified the new function handler with AppSync EvaluateCode on the
APPSYNC_JS 1.0.0 runtime: an unhandled Lambda error is raised, a
successful result passes through unchanged.

Deploying this changes the inline code of every typedErrors pipeline
function; the resolver topology and logical IDs are unchanged.

hoegertn and others added 2 commits October 29, 2026 10:12
With `typedErrors: true`, an untyped error thrown by a resolver handler was
silently swallowed. createAppSyncHandler rethrows untyped errors, so the
Lambda invocation fails and AppSync puts the failure into the pipeline
function's `ctx.error`. The function's response handler returned
`ctx.result` without raising it, so AppSync dropped the error and the field
resolved to `null` with no GraphQL error and HTTP 200. Clients could not
tell a failed mutation from an empty result.

The resolver-level `if (ctx.error) util.appendError(...)` branch could not
catch this: an error left in a pipeline function's `ctx.error` never
reaches the resolver's `ctx.error`. Typed errors (the `__appSyncError`
envelope) were not affected.

Changes:

- The pipeline function now calls `util.error(ctx.error.message, ctx.error.type)`,
  which reports the same message and `Lambda:Unhandled` type a UNIT
  direct-Lambda resolver does.
- Remove the dead `ctx.error` branch from the resolver response handler.
- Correct the `typedErrors` prop doc and llm.md: without the flag the
  Lambda gets no `APPSYNC_TYPED_ERRORS`, so typed errors rethrow and surface
  as `Lambda:Unhandled`, not as envelope field data.
- Add tests that execute the synthesized inline handlers with a fake
  `util`, covering invoke errors, typed envelopes and pass-through results.
  The invoke-error test fails against the previous handler.

Verified the new function handler with AppSync `EvaluateCode` on the
APPSYNC_JS 1.0.0 runtime: an unhandled Lambda error is raised, a
successful result passes through unchanged.

Deploying this changes the inline code of every typedErrors pipeline
function; the resolver topology and logical IDs are unchanged.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@hoegertn
hoegertn merged commit 3a4ac55 into main Oct 29, 2026
4 checks 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