fix(response): route synchronous prepareResponse throws through the error pipeline#1503
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
💤 Files with no reviewable changes (1)
📝 WalkthroughWalkthrough
ChangesResponse preparation correctness
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Thanks. If you like to contribute, can you please split per issue to two prs? |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/errors.test.ts`:
- Around line 298-323: Update the “response preparation throws” tests to run
inside describeMatrix, creating a fresh H3 instance in beforeEach and issuing
requests through ctx.fetch. Preserve both circular return-value and circular
HTTPError assertions while ensuring they execute across the matrix modes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b6dc03c6-7e21-4932-b8ae-ab2a7701e387
📒 Files selected for processing (5)
src/response.tstest/bench/bundle.test.tstest/errors.test.tstest/hooks.test.tstest/middleware.test.ts
…peline A synchronous throw while preparing the response (e.g. JSON.stringify on a circular return value, or on circular error.data in errorResponse) escaped toResponse()/~request() as a raw exception/rejection instead of going through onError/onResponse/logging. prepareResponse() is now called inside a try/catch; a synchronous throw is routed through toError() and re-entered into toResponse(), the same path already used for rejected-promise handlers. Split out of h3js#1503 per maintainer feedback (one PR per issue). Addresses the first bug in h3js#1477; the Uint8Array content-length bug is handled separately. Co-Authored-By: Claude Sonnet 5 <[email protected]>
9aa7d52 to
57b8054
Compare
|
Thanks for the quick review! Split as requested:
Also moved the new tests into |
|
Tip For best results, initiate chat on the files or code changes.
ᕕ( ᐛ )ᕗ🐇 ✏️ Learnings added
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/response.ts`:
- Around line 25-31: Update the synchronous error path in toResponse and the
onError invocation within prepareResponse so a throwing config.onError is
deferred through Promise.resolve().then(...). Ensure its rejection reaches the
existing normalization/error-response handling without recursively calling
toResponse or invoking onError again, while preserving the normalized 500
response behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d371166f-b36d-4f26-9dff-b91fa9b7b169
📒 Files selected for processing (4)
src/response.tstest/bench/bundle.test.tstest/errors.test.tstest/hooks.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- test/errors.test.ts
- test/hooks.test.ts
- test/bench/bundle.test.ts
…nfinitely toResponse()'s try/catch (added for h3js#1477) turns a synchronous throw during response preparation into a call to toResponse(toError(error), ...), which re-enters prepareResponse() with `nested` reset to false. If `onError` itself throws synchronously, `Promise.resolve(onError(error, event))` evaluates that call before wrapping it, so the throw escapes prepareResponse() synchronously instead of becoming a promise rejection — triggering the same onError call again, forever (stack overflow instead of a normalized 500). Move the onError call inside a `.then()`, matching the pattern already used for the onResponse hook below: a synchronous throw there now becomes a rejection, caught by the existing `.catch((error) => error)`, which continues with `nested: true` and terminates the retry. Regression test in errors.test.ts cross-checked against pre-fix code (times out / stack-overflows there). CodeRabbit finding on h3js#1503. Co-Authored-By: Claude Sonnet 5 <[email protected]>
|
Addressed the review:
Thanks @coderabbitai! 🙏 |
|
Tip For best results, initiate chat on the files or code changes.
You’re also right that the ᕕ( ᐛ )ᕗ🐇 |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Part of #1477 (1 of 2 — split per @pi0's request; companion Uint8Array fix in #1504).
Wraps the
prepareResponsecall intoResponseso a synchronous throw during response preparation — e.g.JSON.stringifyon a circular return value, or circularerror.datainsideerrorResponse— is routed through the normal error pipeline (toError→errorResponse) instead of escaping as a raw exception/rejection.onError/onResponseand logging now run, and a500is returned. A non-Errorthrow is handled the same way.Tests (inside
describeMatrix, viat.app/t.fetchper the coding guidelines): a circular return value and a thrownHTTPErrorwith circulardataboth render as500without escaping, and the hook pipeline still fires.pnpm test(lint + format + typecheck + full vitest) is green.Drafted with AI assistance; reviewed and verified against the test suite by me.
Summary by CodeRabbit