Skip to content

Commit 8a58388

Browse files
committed
feat: drop tracing from edge pages runtime wrapping
1 parent 8102dd9 commit 8a58388

File tree

1 file changed

+25
-79
lines changed

1 file changed

+25
-79
lines changed
Lines changed: 25 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,50 @@
1-
import {
2-
captureException,
3-
getActiveSpan,
4-
getCurrentScope,
5-
getRootSpan,
6-
handleCallbackErrors,
7-
SEMANTIC_ATTRIBUTE_SENTRY_OP,
8-
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
9-
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
10-
setCapturedScopesOnSpan,
11-
startSpan,
12-
winterCGRequestToRequestData,
13-
withIsolationScope,
14-
} from '@sentry/core';
15-
import { addHeadersAsAttributes } from '../common/utils/addHeadersAsAttributes';
16-
import { flushSafelyWithTimeout, waitUntil } from '../common/utils/responseEnd';
1+
import { captureException, getIsolationScope, winterCGRequestToRequestData } from '@sentry/core';
2+
import { flushSafelyWithTimeout } from '../common/utils/responseEnd';
173
import type { EdgeRouteHandler } from './types';
184

195
/**
20-
* Wraps a Next.js edge route handler with Sentry error and performance instrumentation.
6+
* Wraps a Next.js edge route handler with Sentry error monitoring.
217
*/
228
export function wrapApiHandlerWithSentry<H extends EdgeRouteHandler>(
239
handler: H,
2410
parameterizedRoute: string,
2511
): (...params: Parameters<H>) => Promise<ReturnType<H>> {
2612
return new Proxy(handler, {
2713
apply: async (wrappingTarget, thisArg, args: Parameters<H>) => {
28-
// TODO: We still should add central isolation scope creation for when our build-time instrumentation does not work anymore with turbopack.
29-
30-
return withIsolationScope(isolationScope => {
14+
try {
3115
const req: unknown = args[0];
32-
const currentScope = getCurrentScope();
3316

34-
let headerAttributes: Record<string, string> = {};
17+
// Set transaction name on isolation scope to ensure parameterized routes are used
18+
// The HTTP server integration sets it on isolation scope, so we need to match that
19+
const isolationScope = getIsolationScope();
3520

3621
if (req instanceof Request) {
22+
const method = req.method || 'GET';
23+
isolationScope.setTransactionName(`${method} ${parameterizedRoute}`);
24+
// Set SDK processing metadata
3725
isolationScope.setSDKProcessingMetadata({
3826
normalizedRequest: winterCGRequestToRequestData(req),
3927
});
40-
currentScope.setTransactionName(`${req.method} ${parameterizedRoute}`);
41-
headerAttributes = addHeadersAsAttributes(req.headers);
4228
} else {
43-
currentScope.setTransactionName(`handler (${parameterizedRoute})`);
29+
isolationScope.setTransactionName(`handler (${parameterizedRoute})`);
4430
}
4531

46-
let spanName: string;
47-
let op: string | undefined = 'http.server';
32+
return await wrappingTarget.apply(thisArg, args);
33+
} catch (error) {
34+
captureException(error, {
35+
mechanism: {
36+
type: 'auto.function.nextjs.wrap_api_handler',
37+
handled: false,
38+
},
39+
});
4840

49-
// If there is an active span, it likely means that the automatic Next.js OTEL instrumentation worked and we can
50-
// rely on that for parameterization.
51-
const activeSpan = getActiveSpan();
52-
if (activeSpan) {
53-
spanName = `handler (${parameterizedRoute})`;
54-
op = undefined;
41+
// we need to await the flush here to ensure that the error is captured
42+
// as the runtime freezes as soon as the error is thrown below
43+
await flushSafelyWithTimeout();
5544

56-
const rootSpan = getRootSpan(activeSpan);
57-
if (rootSpan) {
58-
rootSpan.updateName(
59-
req instanceof Request ? `${req.method} ${parameterizedRoute}` : `handler ${parameterizedRoute}`,
60-
);
61-
rootSpan.setAttributes({
62-
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.server',
63-
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
64-
...headerAttributes,
65-
});
66-
setCapturedScopesOnSpan(rootSpan, currentScope, isolationScope);
67-
}
68-
} else if (req instanceof Request) {
69-
spanName = `${req.method} ${parameterizedRoute}`;
70-
} else {
71-
spanName = `handler ${parameterizedRoute}`;
72-
}
73-
74-
return startSpan(
75-
{
76-
name: spanName,
77-
op: op,
78-
attributes: {
79-
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
80-
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.nextjs.wrap_api_handler',
81-
...headerAttributes,
82-
},
83-
},
84-
() => {
85-
return handleCallbackErrors(
86-
() => wrappingTarget.apply(thisArg, args),
87-
error => {
88-
captureException(error, {
89-
mechanism: {
90-
type: 'auto.function.nextjs.wrap_api_handler',
91-
handled: false,
92-
},
93-
});
94-
},
95-
() => {
96-
waitUntil(flushSafelyWithTimeout());
97-
},
98-
);
99-
},
100-
);
101-
});
45+
// We rethrow here so that nextjs can do with the error whatever it would normally do.
46+
throw error;
47+
}
10248
},
10349
});
10450
}

0 commit comments

Comments
 (0)