11import {
2- SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ,
3- SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ,
42 SPAN_STATUS_ERROR ,
53 addTracingExtensions ,
64 captureException ,
7- continueTrace ,
5+ getActiveSpan ,
6+ getIsolationScope ,
7+ getRootSpan ,
88 handleCallbackErrors ,
99 setHttpStatus ,
10- startSpan ,
11- withIsolationScope ,
1210} from '@sentry/core' ;
1311import { winterCGHeadersToDict } from '@sentry/utils' ;
14-
1512import { isNotFoundNavigationError , isRedirectNavigationError } from './nextNavigationErrorUtils' ;
1613import type { RouteHandlerContext } from './types' ;
1714import { platformSupportsStreaming } from './utils/platformSupportsStreaming' ;
@@ -26,73 +23,55 @@ export function wrapRouteHandlerWithSentry<F extends (...args: any[]) => any>(
2623 context : RouteHandlerContext ,
2724) : ( ...args : Parameters < F > ) => ReturnType < F > extends Promise < unknown > ? ReturnType < F > : Promise < ReturnType < F > > {
2825 addTracingExtensions ( ) ;
29- const { method, parameterizedRoute, headers } = context ;
26+
27+ const { headers } = context ;
28+
3029 return new Proxy ( routeHandler , {
31- apply : ( originalFunction , thisArg , args ) => {
32- return withIsolationScope ( async isolationScope => {
33- isolationScope . setSDKProcessingMetadata ( {
34- request : {
35- headers : headers ? winterCGHeadersToDict ( headers ) : undefined ,
36- } ,
37- } ) ;
38- return continueTrace (
39- {
40- // TODO(v8): Make it so that continue trace will allow null as sentryTrace value and remove this fallback here
41- sentryTrace : headers ?. get ( 'sentry-trace' ) ?? undefined ,
42- baggage : headers ?. get ( 'baggage' ) ,
43- } ,
44- async ( ) => {
45- try {
46- return await startSpan (
47- {
48- op : 'http.server' ,
49- name : `${ method } ${ parameterizedRoute } ` ,
50- forceTransaction : true ,
51- attributes : {
52- [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'route' ,
53- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.function.nextjs' ,
54- } ,
55- } ,
56- async span => {
57- const response : Response = await handleCallbackErrors (
58- ( ) => originalFunction . apply ( thisArg , args ) ,
59- error => {
60- // Next.js throws errors when calling `redirect()`. We don't wanna report these.
61- if ( isRedirectNavigationError ( error ) ) {
62- // Don't do anything
63- } else if ( isNotFoundNavigationError ( error ) ) {
64- span . setStatus ( { code : SPAN_STATUS_ERROR , message : 'not_found' } ) ;
65- } else {
66- captureException ( error , {
67- mechanism : {
68- handled : false ,
69- } ,
70- } ) ;
71- }
72- } ,
73- ) ;
30+ apply : async ( originalFunction , thisArg , args ) => {
31+ getIsolationScope ( ) . setSDKProcessingMetadata ( {
32+ request : {
33+ headers : headers ? winterCGHeadersToDict ( headers ) : undefined ,
34+ } ,
35+ } ) ;
7436
75- try {
76- if ( span && response . status ) {
77- setHttpStatus ( span , response . status ) ;
78- }
79- } catch {
80- // best effort - response may be undefined?
81- }
37+ try {
38+ const activeSpan = getActiveSpan ( ) ;
39+ const rootSpan = activeSpan && getRootSpan ( activeSpan ) ;
8240
83- return response ;
41+ const response : Response = await handleCallbackErrors (
42+ ( ) => originalFunction . apply ( thisArg , args ) ,
43+ error => {
44+ // Next.js throws errors when calling `redirect()`. We don't wanna report these.
45+ if ( isRedirectNavigationError ( error ) ) {
46+ // Don't do anything
47+ } else if ( isNotFoundNavigationError ( error ) && rootSpan ) {
48+ rootSpan . setStatus ( { code : SPAN_STATUS_ERROR , message : 'not_found' } ) ;
49+ } else {
50+ captureException ( error , {
51+ mechanism : {
52+ handled : false ,
8453 } ,
85- ) ;
86- } finally {
87- if ( ! platformSupportsStreaming ( ) || process . env . NEXT_RUNTIME === 'edge' ) {
88- // 1. Edge transport requires manual flushing
89- // 2. Lambdas require manual flushing to prevent execution freeze before the event is sent
90- await flushQueue ( ) ;
91- }
54+ } ) ;
9255 }
9356 } ,
9457 ) ;
95- } ) ;
58+
59+ try {
60+ if ( rootSpan && response . status ) {
61+ setHttpStatus ( rootSpan , response . status ) ;
62+ }
63+ } catch {
64+ // best effort - response may be undefined?
65+ }
66+
67+ return response ;
68+ } finally {
69+ if ( ! platformSupportsStreaming ( ) || process . env . NEXT_RUNTIME === 'edge' ) {
70+ // 1. Edge transport requires manual flushing
71+ // 2. Lambdas require manual flushing to prevent execution freeze before the event is sent
72+ await flushQueue ( ) ;
73+ }
74+ }
9675 } ,
9776 } ) ;
9877}
0 commit comments