55 captureException ,
66 getActiveSpan ,
77 getCapturedScopesOnSpan ,
8+ getIsolationScope ,
89 getRootSpan ,
910 handleCallbackErrors ,
1011 setCapturedScopesOnSpan ,
@@ -16,9 +17,8 @@ import {
1617import type { RouteHandlerContext } from './types' ;
1718
1819import { propagationContextFromHeaders , winterCGHeadersToDict } from '@sentry/utils' ;
19-
2020import { isNotFoundNavigationError , isRedirectNavigationError } from './nextNavigationErrorUtils' ;
21- import { commonObjectToIsolationScope , commonObjectToPropagationContext } from './utils/tracingUtils' ;
21+ import { commonObjectToIsolationScope } from './utils/tracingUtils' ;
2222
2323/**
2424 * Wraps a Next.js App Router Route handler with Sentry error and performance instrumentation.
@@ -34,82 +34,77 @@ export function wrapRouteHandlerWithSentry<F extends (...args: any[]) => any>(
3434
3535 return new Proxy ( routeHandler , {
3636 apply : async ( originalFunction , thisArg , args ) => {
37- const isolationScope = commonObjectToIsolationScope ( headers ) ;
38-
39- const completeHeadersDict : Record < string , string > = headers ? winterCGHeadersToDict ( headers ) : { } ;
40-
41- isolationScope . setSDKProcessingMetadata ( {
42- request : {
43- url : parameterizedRoute ,
44- method,
45- headers : completeHeadersDict ,
46- } ,
47- } ) ;
48-
49- const incomingPropagationContext = propagationContextFromHeaders (
50- completeHeadersDict [ 'sentry-trace' ] ,
51- completeHeadersDict [ 'baggage' ] ,
52- ) ;
53-
54- const propagationContext = commonObjectToPropagationContext ( headers , incomingPropagationContext ) ;
55-
5637 const activeSpan = getActiveSpan ( ) ;
5738 const rootSpan = activeSpan ? getRootSpan ( activeSpan ) : undefined ;
58- if ( rootSpan ) {
39+
40+ let edgeRuntimeIsolationScopeOverride : Scope | undefined ;
41+ if ( rootSpan && process . env . NEXT_RUNTIME === 'edge' ) {
42+ const isolationScope = commonObjectToIsolationScope ( headers ) ;
5943 const { scope } = getCapturedScopesOnSpan ( rootSpan ) ;
6044 setCapturedScopesOnSpan ( rootSpan , scope ?? new Scope ( ) , isolationScope ) ;
6145
62- if ( process . env . NEXT_RUNTIME === 'edge' ) {
63- rootSpan . updateName ( ` ${ method } ${ parameterizedRoute } ` ) ;
64- rootSpan . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , 'route' ) ;
65- rootSpan . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_OP , 'http.server ' ) ;
66- }
46+ edgeRuntimeIsolationScopeOverride = isolationScope ;
47+
48+ rootSpan . updateName ( ` ${ method } ${ parameterizedRoute } ` ) ;
49+ rootSpan . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , 'route ' ) ;
50+ rootSpan . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_OP , 'http.server' ) ;
6751 }
6852
69- return withIsolationScope ( isolationScope , ( ) => {
70- return withScope ( async scope => {
71- scope . setTransactionName ( `${ method } ${ parameterizedRoute } ` ) ;
72- scope . setPropagationContext ( propagationContext ) ;
53+ return withIsolationScope (
54+ process . env . NEXT_RUNTIME === 'edge' ? edgeRuntimeIsolationScopeOverride : getIsolationScope ( ) ,
55+ ( ) => {
56+ return withScope ( async scope => {
57+ scope . setTransactionName ( `${ method } ${ parameterizedRoute } ` ) ;
7358
74- const response : Response = await handleCallbackErrors (
75- ( ) => originalFunction . apply ( thisArg , args ) ,
76- error => {
77- // Next.js throws errors when calling `redirect()`. We don't wanna report these.
78- if ( isRedirectNavigationError ( error ) ) {
79- // Don't do anything
80- } else if ( isNotFoundNavigationError ( error ) ) {
59+ if ( process . env . NEXT_RUNTIME === 'edge' ) {
60+ const completeHeadersDict : Record < string , string > = headers ? winterCGHeadersToDict ( headers ) : { } ;
61+ const incomingPropagationContext = propagationContextFromHeaders (
62+ completeHeadersDict [ 'sentry-trace' ] ,
63+ completeHeadersDict [ 'baggage' ] ,
64+ ) ;
65+ scope . setPropagationContext ( incomingPropagationContext ) ;
66+ }
67+
68+ const response : Response = await handleCallbackErrors (
69+ ( ) => originalFunction . apply ( thisArg , args ) ,
70+ error => {
71+ // Next.js throws errors when calling `redirect()`. We don't wanna report these.
72+ if ( isRedirectNavigationError ( error ) ) {
73+ // Don't do anything
74+ } else if ( isNotFoundNavigationError ( error ) ) {
75+ if ( activeSpan ) {
76+ setHttpStatus ( activeSpan , 404 ) ;
77+ }
78+ if ( rootSpan ) {
79+ setHttpStatus ( rootSpan , 404 ) ;
80+ }
81+ } else {
82+ captureException ( error , {
83+ mechanism : {
84+ handled : false ,
85+ } ,
86+ } ) ;
87+ }
88+ } ,
89+ ) ;
90+
91+ try {
92+ if ( response . status ) {
8193 if ( activeSpan ) {
82- setHttpStatus ( activeSpan , 404 ) ;
94+ setHttpStatus ( activeSpan , response . status ) ;
8395 }
8496 if ( rootSpan ) {
85- setHttpStatus ( rootSpan , 404 ) ;
97+ setHttpStatus ( rootSpan , response . status ) ;
8698 }
87- } else {
88- captureException ( error , {
89- mechanism : {
90- handled : false ,
91- } ,
92- } ) ;
93- }
94- } ,
95- ) ;
96-
97- try {
98- if ( response . status ) {
99- if ( activeSpan ) {
100- setHttpStatus ( activeSpan , response . status ) ;
101- }
102- if ( rootSpan ) {
103- setHttpStatus ( rootSpan , response . status ) ;
10499 }
100+ } catch {
101+ // best effort - response may be undefined?
105102 }
106- } catch {
107- // best effort - response may be undefined?
108- }
109103
110- return response ;
111- } ) ;
112- } ) ;
104+ return response ;
105+ } ) ;
106+ } ,
107+ ) ;
113108 } ,
114109 } ) ;
115110}
0 commit comments