Skip to content

Commit d452bdb

Browse files
committed
fix: added captureError callback so integrations can set their own mechanisms
1 parent a11202f commit d452bdb

3 files changed

Lines changed: 26 additions & 11 deletions

File tree

dev-packages/e2e-tests/test-applications/nitro-3/tests/errors.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ test('Sends an error event to Sentry', async ({ request }) => {
1717
expect(errorEvent.exception?.values?.[0]?.mechanism).toEqual(
1818
expect.objectContaining({
1919
handled: false,
20-
type: 'auto.diagnostic_channels.bind_span',
20+
type: 'auto.http.nitro.onTraceError',
2121
}),
2222
);
2323
});

packages/nitro/src/runtime/hooks/captureTracingEvents.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ function setupH3TracingChannels(): void {
108108
return span;
109109
},
110110
{
111+
captureError: () => ({
112+
mechanism: {
113+
handled: false,
114+
type: 'auto.http.nitro.onTraceError',
115+
},
116+
}),
111117
beforeSpanEnd(span, data) {
112118
applyResponseStatus(span, data);
113119

packages/server-utils/src/tracing-channel.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { TracingChannel, TracingChannelSubscribers } from 'node:diagnostics_channel';
22
import type { AsyncLocalStorage } from 'node:async_hooks';
3-
import type { Span } from '@sentry/core';
3+
import type { ExclusiveEventHintOrCaptureContext, Span } from '@sentry/core';
44
import { _INTERNAL_getTracingChannelBinding, debug, captureException, SPAN_STATUS_ERROR } from '@sentry/core';
55
import { DEBUG_BUILD } from './debug-build';
66

@@ -39,11 +39,11 @@ interface TracingChannelAutoBindingOptions<TData extends object = object> {
3939
beforeSpanEnd?: (span: Span, data: TracingChannelPayloadWithSpan<TData>) => void;
4040

4141
/**
42-
* Whether a thrown error is captured as a Sentry event. The span is always marked with error
43-
* status regardless. Defaults to `true`.
42+
* Whether a thrown error is captured as a Sentry event. The span is always marked with error status regardless. Defaults to `true`.
43+
* You can alternatively pass a function that sets the ExclusiveEventHintOrCaptureContext on the captured error.
4444
* Set `false` for instrumentation that only annotates the span and lets the error be captured at the boundary that owns it (e.g. db spans).
4545
*/
46-
captureError?: boolean;
46+
captureError?: boolean | ((e: unknown) => ExclusiveEventHintOrCaptureContext);
4747
}
4848

4949
export type TracingChannelBindingOptions<TData extends object = object> =
@@ -95,6 +95,19 @@ export function bindTracingChannelToSpan<TData extends object>(
9595

9696
const beforeSpanEnd = opts?.beforeSpanEnd;
9797

98+
const getErrorHint = (e: unknown) => {
99+
if (typeof opts?.captureError === 'function') {
100+
return opts.captureError(e);
101+
}
102+
103+
return {
104+
mechanism: {
105+
type: 'auto.diagnostic_channels.bind_span',
106+
handled: false,
107+
},
108+
};
109+
};
110+
98111
const subscribers: Partial<TracingChannelSubscribers<TracingChannelPayloadWithSpan<TData>>> = {
99112
start: NOOP,
100113
asyncStart: NOOP,
@@ -107,13 +120,9 @@ export function bindTracingChannelToSpan<TData extends object>(
107120
},
108121
error(data) {
109122
if (opts?.captureError !== false) {
110-
captureException(data.error, {
111-
mechanism: {
112-
type: 'auto.diagnostic_channels.bind_span',
113-
handled: false,
114-
},
115-
});
123+
captureException(data.error, getErrorHint(data.error));
116124
}
125+
117126
data._sentrySpan?.setStatus({ code: SPAN_STATUS_ERROR, message: getErrorMessage(data.error) });
118127
},
119128
asyncEnd(data) {

0 commit comments

Comments
 (0)