Skip to content

fix(fastify): catch thrown route errors - #937

Merged
proggeramlug merged 1 commit into
PerryTS:mainfrom
andrewtdiz:codex/issue-928-fastify-error-boundary
May 17, 2026
Merged

fix(fastify): catch thrown route errors#937
proggeramlug merged 1 commit into
PerryTS:mainfrom
andrewtdiz:codex/issue-928-fastify-error-boundary

Conversation

@andrewtdiz

@andrewtdiz andrewtdiz commented May 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #928.

  • Add Perry try/setjmp traps around native Fastify route handlers, onRequest/preHandler hooks, and custom setErrorHandler callbacks in both perry-ext-fastify and the in-tree stdlib Fastify implementation.
  • Normalize sync throws and rejected Promises into Fastify-style error responses instead of letting js_throw exit the process when no try frame is active.
  • Render built-in runtime Error values through js_error_get_message so default 500 bodies are stable and do not use generic JSON stringify on ErrorHeader.
  • Add sync/async thrown-route regression coverage and assert the server remains alive after both failures.

Root Cause

Async flag propagation was not the primary issue: async arrows/functions already reject their returned Promise for top-level throws. The native Fastify bridge was missing the framework error boundary. It invoked raw Perry closures from Rust without an active js_try_push frame, so sync throws from handlers, hooks, or nested helpers reached js_throw with TRY_DEPTH == 0 and terminated the process.

Verification

  • cargo fmt --check
  • cargo check -p perry-stdlib -p perry-ext-fastify
  • cargo build --release -p perry -p perry-runtime -p perry-stdlib -p perry-ext-fastify
  • PERRY_BIN="$PWD/target/release/perry" scripts/run_fastify_tests.shfastify-tests: 10 passed, 0 failed
  • cargo test --release -p perry-ext-fastify — 10 passed
  • cargo test --release -p perry-stdlib fastify — 22 passed

Contributor Metadata

Per CONTRIBUTING.md, this PR does not bump [workspace.package], CLAUDE.md, or CHANGELOG.md; release metadata is left for the maintainer at merge time.

@andrewtdiz
andrewtdiz force-pushed the codex/issue-928-fastify-error-boundary branch from d217e40 to 41619d5 Compare May 17, 2026 16:42
@andrewtdiz
andrewtdiz force-pushed the codex/issue-928-fastify-error-boundary branch from 41619d5 to 7d39911 Compare May 17, 2026 16:57
@proggeramlug
proggeramlug merged commit 4943407 into PerryTS:main May 17, 2026
7 of 9 checks passed
proggeramlug added a commit that referenced this pull request May 17, 2026
…-in Error layout (#939)

stringify_value and stringify_value_depth dispatched GC_TYPE_ERROR
through the catch-all -> is_object_pointer -> stringify_object path,
which derefed ErrorHeader::error_kind as a keys_array pointer and
crashed the process. Add an explicit GC_TYPE_ERROR arm in both that
emits "{}" — matches Node's JSON.stringify(new Error("x")) behavior
(Error's intrinsic props are non-enumerable per spec). Closes the
js_json_stringify fallback hole in the Fastify rejection-body
renderer that PR #937 added the catch path for.
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.

throw new Error(...) in async Fastify route handler crashes process (exit 1) instead of being caught by setErrorHandler

2 participants