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,80 +34,83 @@ 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- headers : completeHeadersDict ,
44- } ,
45- } ) ;
46-
47- const incomingPropagationContext = propagationContextFromHeaders (
48- completeHeadersDict [ 'sentry-trace' ] ,
49- completeHeadersDict [ 'baggage' ] ,
50- ) ;
51-
52- const propagationContext = commonObjectToPropagationContext ( headers , incomingPropagationContext ) ;
53-
5437 const activeSpan = getActiveSpan ( ) ;
5538 const rootSpan = activeSpan ? getRootSpan ( activeSpan ) : undefined ;
56- if ( rootSpan ) {
39+
40+ let edgeRuntimeIsolationScopeOverride : Scope | undefined ;
41+ if ( rootSpan && process . env . NEXT_RUNTIME === 'edge' ) {
42+ const isolationScope = commonObjectToIsolationScope ( headers ) ;
5743 const { scope } = getCapturedScopesOnSpan ( rootSpan ) ;
5844 setCapturedScopesOnSpan ( rootSpan , scope ?? new Scope ( ) , isolationScope ) ;
5945
60- if ( process . env . NEXT_RUNTIME === 'edge' ) {
61- rootSpan . updateName ( ` ${ method } ${ parameterizedRoute } ` ) ;
62- rootSpan . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , 'route' ) ;
63- rootSpan . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_OP , 'http.server ' ) ;
64- }
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' ) ;
6551 }
6652
67- return withIsolationScope ( isolationScope , ( ) => {
68- return withScope ( async scope => {
69- scope . setTransactionName ( `${ method } ${ parameterizedRoute } ` ) ;
70- 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 } ` ) ;
7158
72- const response : Response = await handleCallbackErrors (
73- ( ) => originalFunction . apply ( thisArg , args ) ,
74- error => {
75- // Next.js throws errors when calling `redirect()`. We don't wanna report these.
76- if ( isRedirectNavigationError ( error ) ) {
77- // Don't do anything
78- } 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+ scope . setSDKProcessingMetadata ( {
67+ request : {
68+ method,
69+ headers : completeHeadersDict ,
70+ } ,
71+ } ) ;
72+ }
73+
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 ) ) {
81+ if ( activeSpan ) {
82+ setHttpStatus ( activeSpan , 404 ) ;
83+ }
84+ if ( rootSpan ) {
85+ setHttpStatus ( rootSpan , 404 ) ;
86+ }
87+ } else {
88+ captureException ( error , {
89+ mechanism : {
90+ handled : false ,
91+ } ,
92+ } ) ;
93+ }
94+ } ,
95+ ) ;
96+
97+ try {
98+ if ( response . status ) {
7999 if ( activeSpan ) {
80- setHttpStatus ( activeSpan , 404 ) ;
100+ setHttpStatus ( activeSpan , response . status ) ;
81101 }
82102 if ( rootSpan ) {
83- setHttpStatus ( rootSpan , 404 ) ;
103+ setHttpStatus ( rootSpan , response . status ) ;
84104 }
85- } else {
86- captureException ( error , {
87- mechanism : {
88- handled : false ,
89- } ,
90- } ) ;
91- }
92- } ,
93- ) ;
94-
95- try {
96- if ( response . status ) {
97- if ( activeSpan ) {
98- setHttpStatus ( activeSpan , response . status ) ;
99- }
100- if ( rootSpan ) {
101- setHttpStatus ( rootSpan , response . status ) ;
102105 }
106+ } catch {
107+ // best effort - response may be undefined?
103108 }
104- } catch {
105- // best effort - response may be undefined?
106- }
107109
108- return response ;
109- } ) ;
110- } ) ;
110+ return response ;
111+ } ) ;
112+ } ,
113+ ) ;
111114 } ,
112115 } ) ;
113116}
0 commit comments