Skip to content

fix: set status code before publishing diagnostics error channel#6412

Merged
Eomm merged 3 commits intofastify:mainfrom
tt-a1i:fix/diagnostics-channel-error-status-code
Dec 14, 2025
Merged

fix: set status code before publishing diagnostics error channel#6412
Eomm merged 3 commits intofastify:mainfrom
tt-a1i:fix/diagnostics-channel-error-status-code

Conversation

@tt-a1i
Copy link
Contributor

@tt-a1i tt-a1i commented Dec 11, 2025

Summary

Fixes #6409

Previously, the tracing:fastify.request.handler:error diagnostics channel would always report reply.statusCode as 200 because the channel was published before the error handler had a chance to set the appropriate status code.

This fix sets the status code based on the error's statusCode or status property before publishing the diagnostics channel event, so subscribers can see the correct status code.

Changes

  • lib/handle-request.js: Set status code before publishing error channel (both sync error paths)
  • lib/wrap-thenable.js: Set status code before publishing error channel (async error path)
  • Added tests verifying the fix

Test plan

  • Added test: diagnostics channel error event should report correct status code - verifies error with statusCode
  • Added test: diagnostics channel error event should report 500 for errors without status - verifies plain errors default to 500
  • Added test: diagnostics channel error event should report correct status with custom error handler - documents behavior with custom error handlers
  • All existing tests pass

Previously, the `tracing:fastify.request.handler:error` diagnostics channel
would always report `reply.statusCode` as 200 because the channel was
published before the error handler had a chance to set the appropriate
status code.

This fix sets the status code based on the error's `statusCode` or `status`
property before publishing the diagnostics channel event, so subscribers
can see the correct status code.

Fixes fastify#6409
@tt-a1i
Copy link
Contributor Author

tt-a1i commented Dec 11, 2025

One thing I'd like to discuss about this implementation:

The condition check

I copied the exact logic from defaultErrorHandler in error-handler.js:

if (!reply[kReplyHasStatusCode] || reply.statusCode === 200) {

However, I'm wondering if this condition might be slightly off semantically. If a user explicitly calls reply.code(200) before throwing an error, kReplyHasStatusCode would be true, but statusCode === 200 is also true, so the condition passes and we'd still override it.

Technically, if the user explicitly set a status code, we probably shouldn't override it regardless of the value. So a stricter check would be:

if (!reply[kReplyHasStatusCode]) {

That said, the current logic matches defaultErrorHandler's behavior, and the scenario of explicitly setting 200 then throwing an error is pretty rare in practice.

Should I:

  1. Keep it as-is to match defaultErrorHandler behavior (current implementation)
  2. Simplify to just !reply[kReplyHasStatusCode] (and potentially update defaultErrorHandler too for consistency)

Happy to go either way based on your preference!

Address reviewer feedback:
- Extract repeated status code logic into reusable setErrorStatusCode function
- Create lib/error-status.js to avoid circular dependency with reply.js
- Simplify test inject calls using shorthand syntax
@tt-a1i
Copy link
Contributor Author

tt-a1i commented Dec 14, 2025

Thanks for the review! I've addressed your feedback:

  1. Extracted the repeated logic into a dedicated setErrorStatusCode function
  2. Simplified the inject calls in tests using shorthand syntax

I initially tried adding the function to Reply.js as suggested, but it caused a circular dependency warning (reply.jshandle-request.jsreply.js). So I created a separate lib/error-status.js module instead, which follows the naming pattern of error-handler.js and error-serializer.js.

The extracted function also includes a null check (err &&) that was present in error-handler.js but missing in my original implementation - this makes the code more robust.

@Eomm Eomm added the bugfix Issue or PR that should land as semver patch label Dec 14, 2025
Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@Eomm Eomm merged commit 970c575 into fastify:main Dec 14, 2025
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Issue or PR that should land as semver patch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error diagnostic channel always sends 200 unless explicitly changed

3 participants