Skip to content

Commit 53d3aac

Browse files
committed
feat(node): Use diagnostics channel for Fastify v5 error handling
1 parent c37d4e5 commit 53d3aac

File tree

2 files changed

+30
-10
lines changed
  • dev-packages/e2e-tests/test-applications/node-fastify-5/src
  • packages/node/src/integrations/tracing/fastify

2 files changed

+30
-10
lines changed

dev-packages/e2e-tests/test-applications/node-fastify-5/src/app.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ const app = fastify();
3434
const port = 3030;
3535
const port2 = 3040;
3636

37-
Sentry.setupFastifyErrorHandler(app);
38-
3937
app.get('/test-success', function (_req, res) {
4038
res.send({ version: 'v1' });
4139
});

packages/node/src/integrations/tracing/fastify/index.ts

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ export const instrumentFastifyV3 = generateInstrumentOnce(INTEGRATION_NAME_V3, (
6060
export const instrumentFastify = generateInstrumentOnce(INTEGRATION_NAME, () => {
6161
const fastifyOtelInstrumentationInstance = new FastifyOtelInstrumentation();
6262
const plugin = fastifyOtelInstrumentationInstance.plugin();
63+
const options = fastifyOtelInstrumentationInstance.getConfig();
64+
const shouldHandleError = (options as FastifyHandlerOptions)?.shouldHandleError || defaultShouldHandleError;
6365

6466
// This message handler works for Fastify versions 3, 4 and 5
6567
diagnosticsChannel.subscribe('fastify.initialization', message => {
@@ -78,8 +80,22 @@ export const instrumentFastify = generateInstrumentOnce(INTEGRATION_NAME, () =>
7880
});
7981
});
8082

83+
// This diagnostics channel only works on Fastify version 5
84+
// For versions 3 and 4, we use `setupFastifyErrorHandler` instead
85+
diagnosticsChannel.subscribe('tracing:fastify.request.handler:error', message => {
86+
const { error, request, reply } = message as {
87+
error: Error;
88+
request: FastifyRequest & { opentelemetry?: () => { span?: Span } };
89+
reply: FastifyReply;
90+
};
91+
92+
if (shouldHandleError(error, request, reply)) {
93+
captureException(error);
94+
}
95+
});
96+
8197
// Returning this as unknown not to deal with the internal types of the FastifyOtelInstrumentation
82-
return fastifyOtelInstrumentationInstance as Instrumentation<InstrumentationConfig>;
98+
return fastifyOtelInstrumentationInstance as Instrumentation<InstrumentationConfig & FastifyHandlerOptions>;
8399
});
84100

85101
const _fastifyIntegration = (() => {
@@ -143,15 +159,21 @@ function defaultShouldHandleError(_error: Error, _request: FastifyRequest, reply
143159
*/
144160
export function setupFastifyErrorHandler(fastify: FastifyInstance, options?: Partial<FastifyHandlerOptions>): void {
145161
const shouldHandleError = options?.shouldHandleError || defaultShouldHandleError;
146-
147162
const plugin = Object.assign(
148163
function (fastify: FastifyInstance, _options: unknown, done: () => void): void {
149-
fastify.addHook('onError', async (request, reply, error) => {
150-
if (shouldHandleError(error, request, reply)) {
151-
captureException(error);
152-
}
153-
});
154-
164+
if (fastify.version?.startsWith('5.')) {
165+
// Fastify 5.x uses diagnostics channel for error handling
166+
DEBUG_BUILD &&
167+
logger.warn(
168+
'Fastify 5.x detected, using diagnostics channel for error handling.\nYou can safely remove `setupFastifyErrorHandler` call.',
169+
);
170+
} else {
171+
fastify.addHook('onError', async (request, reply, error) => {
172+
if (shouldHandleError(error, request, reply)) {
173+
captureException(error);
174+
}
175+
});
176+
}
155177
done();
156178
},
157179
{

0 commit comments

Comments
 (0)