Skip to content

Commit f2e4a82

Browse files
committed
improve route handler tx name
1 parent 99a8159 commit f2e4a82

File tree

2 files changed

+24
-99
lines changed

2 files changed

+24
-99
lines changed
Lines changed: 7 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,8 @@
1-
import {
2-
SEMANTIC_ATTRIBUTE_SENTRY_OP,
3-
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
4-
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
5-
SPAN_STATUS_ERROR,
6-
Scope,
7-
captureException,
8-
getActiveSpan,
9-
getCapturedScopesOnSpan,
10-
getRootSpan,
11-
handleCallbackErrors,
12-
setCapturedScopesOnSpan,
13-
setHttpStatus,
14-
startSpan,
15-
withIsolationScope,
16-
withScope,
17-
} from '@sentry/core';
18-
import { propagationContextFromHeaders, winterCGHeadersToDict } from '@sentry/utils';
19-
import { isNotFoundNavigationError, isRedirectNavigationError } from './nextNavigationErrorUtils';
1+
import { Scope, getActiveSpan, getCapturedScopesOnSpan, getRootSpan, setCapturedScopesOnSpan } from '@sentry/core';
2+
203
import type { RouteHandlerContext } from './types';
21-
import { flushSafelyWithTimeout } from './utils/responseEnd';
22-
import {
23-
commonObjectToIsolationScope,
24-
commonObjectToPropagationContext,
25-
escapeNextjsTracing,
26-
} from './utils/tracingUtils';
27-
import { vercelWaitUntil } from './utils/vercelWaitUntil';
4+
5+
import { commonObjectToIsolationScope } from './utils/tracingUtils';
286

297
/**
308
* Wraps a Next.js App Router Route handler with Sentry error and performance instrumentation.
@@ -36,7 +14,7 @@ export function wrapRouteHandlerWithSentry<F extends (...args: any[]) => any>(
3614
routeHandler: F,
3715
context: RouteHandlerContext,
3816
): (...args: Parameters<F>) => ReturnType<F> extends Promise<unknown> ? ReturnType<F> : Promise<ReturnType<F>> {
39-
const { method, parameterizedRoute, headers } = context;
17+
const { headers } = context;
4018

4119
return new Proxy(routeHandler, {
4220
apply: (originalFunction, thisArg, args) => {
@@ -48,77 +26,12 @@ export function wrapRouteHandlerWithSentry<F extends (...args: any[]) => any>(
4826
const { scope } = getCapturedScopesOnSpan(rootSpan);
4927
setCapturedScopesOnSpan(rootSpan, scope ?? new Scope(), isolationScope);
5028

51-
// We mark the root span as an app route handler span so we can allow-list it in our span processor that would normally filter out all Next.js transactions/spans
29+
// We mark the root span as an app route handler span so we can allow-list it in our span processor
30+
// that would normally filter out all Next.js transactions/spans
5231
rootSpan.setAttribute('sentry.route_handler', true);
5332
}
5433

5534
return originalFunction.apply(thisArg, args);
56-
57-
// const completeHeadersDict: Record<string, string> = headers ? winterCGHeadersToDict(headers) : {};
58-
59-
// isolationScope.setSDKProcessingMetadata({
60-
// request: {
61-
// headers: completeHeadersDict,
62-
// },
63-
// });
64-
65-
// const incomingPropagationContext = propagationContextFromHeaders(
66-
// completeHeadersDict['sentry-trace'],
67-
// completeHeadersDict['baggage'],
68-
// );
69-
70-
// const propagationContext = commonObjectToPropagationContext(headers, incomingPropagationContext);
71-
72-
// return withIsolationScope(isolationScope, () => {
73-
// return withScope(async scope => {
74-
// scope.setTransactionName(`${method} ${parameterizedRoute}`);
75-
// scope.setPropagationContext(propagationContext);
76-
// try {
77-
// return startSpan(
78-
// {
79-
// name: `${method} ${parameterizedRoute}`,
80-
// attributes: {
81-
// [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
82-
// [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.server',
83-
// [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.nextjs',
84-
// },
85-
// forceTransaction: true,
86-
// },
87-
// async span => {
88-
// const response: Response = await handleCallbackErrors(
89-
// () => originalFunction.apply(thisArg, args),
90-
// error => {
91-
// // Next.js throws errors when calling `redirect()`. We don't wanna report these.
92-
// if (isRedirectNavigationError(error)) {
93-
// // Don't do anything
94-
// } else if (isNotFoundNavigationError(error) && span) {
95-
// span.setStatus({ code: SPAN_STATUS_ERROR, message: 'not_found' });
96-
// } else {
97-
// captureException(error, {
98-
// mechanism: {
99-
// handled: false,
100-
// },
101-
// });
102-
// }
103-
// },
104-
// );
105-
106-
// try {
107-
// if (span && response.status) {
108-
// setHttpStatus(span, response.status);
109-
// }
110-
// } catch {
111-
// // best effort - response may be undefined?
112-
// }
113-
114-
// return response;
115-
// },
116-
// );
117-
// } finally {
118-
// vercelWaitUntil(flushSafelyWithTimeout());
119-
// }
120-
// });
121-
// });
12235
},
12336
});
12437
}

packages/nextjs/src/server/index.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@ export function init(options: NodeOptions): NodeClient | undefined {
211211
return null;
212212
}
213213

214-
// We only want to use our HTTP integration/instrumentation for app router requests, which are marked with the `sentry.rsc` attribute.
214+
// We only want to use our HTTP integration/instrumentation for app router requests,
215+
// which are marked with the `sentry.rsc` or `sentry.route_handler` attribute.
215216
if (
216217
(event.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] === 'auto.http.otel.http' ||
217218
event.contexts?.trace?.data?.['next.span_type'] === 'BaseServer.handleRequest') &&
@@ -296,17 +297,28 @@ export function init(options: NodeOptions): NodeClient | undefined {
296297
// Next.js that are actually more or less correct server HTTP spans, so we are backfilling the op here.
297298
if (
298299
event.type === 'transaction' &&
299-
(event.transaction?.match(/^(RSC )?GET /) ||
300-
event.transaction?.match(/^(GET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS|TRACE|PATCH) \/api$/)) &&
301-
(event.contexts?.trace?.data?.['sentry.rsc'] === true ||
302-
event.contexts?.trace?.data?.['sentry.route_handler'] === true) &&
300+
event.transaction?.match(/^(RSC )?GET /) &&
301+
event.contexts?.trace?.data?.['sentry.rsc'] === true &&
303302
!event.contexts?.trace?.op
304303
) {
305304
event.contexts.trace.data = event.contexts.trace.data || {};
306305
event.contexts.trace.data[SEMANTIC_ATTRIBUTE_SENTRY_OP] = 'http.server';
307306
event.contexts.trace.op = 'http.server';
308307
}
309308

309+
// Enhance route handler transactions
310+
if (
311+
event.type === 'transaction' &&
312+
event.transaction?.match(/^(GET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS|TRACE|PATCH) \/api/) &&
313+
event.contexts?.trace?.data?.['sentry.route_handler'] === true &&
314+
!event.contexts.trace.op
315+
) {
316+
event.contexts.trace.data = event.contexts.trace.data || {};
317+
event.contexts.trace.data[SEMANTIC_ATTRIBUTE_SENTRY_OP] = 'http.server';
318+
event.contexts.trace.op = 'http.server';
319+
event.transaction = event.transaction.replace(/\/route$/, '');
320+
}
321+
310322
return event;
311323
}) satisfies EventProcessor,
312324
{ id: 'NextjsTransactionEnhancer' },

0 commit comments

Comments
 (0)