Skip to content

Fastify 5 integration: reply.statusCode  is always 200 in  shouldHandleError , making docs example unusable #18418

@irsooti

Description

@irsooti

Is there an existing issue for this?

How do you use Sentry?

Self-hosted/on-premise

Which SDK are you using?

@sentry/node

SDK Version

10.29.0

Framework Version

Fastify 5.4.0

Link to Sentry event

No response

Reproduction Example/SDK Setup

Hi,
while integrating Sentry with Fastify I ran into a few problems with the Fastify integration, mainly:

  • Handling Fastify errors (for example validation errors, which are “handled” in theory)
  • Handling errors from  @fastify/sensible  (which are handled, but only from 500 upwards)

The docs suggest a very simple approach: check reply.statusCode  inside  shouldHandleError  to decide whether an error should be captured. However, in my case  reply.statusCode  is always 200  inside shouldHandleError.

I do not override the status code anywhere, and I do not have any custom error handler that would reset it. This was quite frustrating because the recommended pattern in the docs becomes effectively unusable.
Because of this, I had to fall back to a more ad‑hoc implementation, where I decide what to send to Sentry based only on the error type/name, instead of the HTTP status code. This is what I ended up with (simplified):

Sentry.init({
    enabled: env.SENTRY_ENABLED,
    dsn: env.SENTRY_DSN,
    environment: env.SENTRY_ENVIRONMENT,
    release: `${env.npm_package_name}-${env.npm_package_version}`,
    sampleRate: env.SENTRY_SAMPLE_RATE,
    integrations: [
        Sentry.fastifyIntegration({
            shouldHandleError(err) {
                // Ignore 4xx from @fastify/sensible
                if (SENSIBLE_4XX_ERRORS.includes(err.name)) {
                    return false;
                }

                // Ignore all Fastify 4xx errors
                if (shouldIgnoreFastifyError(err)) {
                    return false;
                }

                return true;
            },
        }),
    ],
    beforeSend: (event, hint) => {
        if (
            hint.originalException instanceof Error &&
            SENSIBLE_5XX_ERRORS.includes(hint.originalException.name)
        ) {
            event.exception?.values?.forEach((value) => {
                value.mechanism = {
                    type: 'fastify.sensible',
                    handled: true,
                };
            });
        }

        return event;
    },
});

This works and should not drop important errors, but it is much less granular and much less clear than checking  reply.statusCode  as shown in the docs. It also means I cannot easily separate 4xx vs 5xx just by looking at the response.
A few questions / suggestions:

  • Is  reply.statusCode  supposed to be meaningful inside  shouldHandleError  for the Fastify integration, or is it expected to be  200  there?
  • If this is expected, the docs example using  reply.statusCode  is at least misleading and should probably be updated or clarified.
  • If this is not expected, it might be a bug either in the integration or in how the Fastify reply object is passed.

Steps to Reproduce

Just tried as documentation says:

Sentry.init({
    enabled: env.SENTRY_ENABLED,
    dsn: env.SENTRY_DSN,
    environment: env.SENTRY_ENVIRONMENT,
    release: `${env.npm_package_name}-${env.npm_package_version}`,
    sampleRate: env.SENTRY_SAMPLE_RATE,
    integrations: [
        Sentry.fastifyIntegration({
            shouldHandleError(err) {
              // what you suggested
            },
        }),
    ]
    },
});

Expected Result

  • Ignore validation errors;
  • Ignore 400;

Actual Result

No logs, but always 200

Additional Context

No response

Priority

React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it.

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    Waiting for: Product Owner

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions