11import type { RequestEventData } from '@sentry/core' ;
2- import {
3- captureException ,
4- getActiveSpan ,
5- getCapturedScopesOnSpan ,
6- getRootSpan ,
7- handleCallbackErrors ,
8- propagationContextFromHeaders ,
9- Scope ,
10- SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ,
11- SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ,
12- setCapturedScopesOnSpan ,
13- SPAN_STATUS_ERROR ,
14- SPAN_STATUS_OK ,
15- startSpanManual ,
16- winterCGHeadersToDict ,
17- withIsolationScope ,
18- withScope ,
19- } from '@sentry/core' ;
2+ import { captureException , handleCallbackErrors , winterCGHeadersToDict , withIsolationScope } from '@sentry/core' ;
203import { isNotFoundNavigationError , isRedirectNavigationError } from '../common/nextNavigationErrorUtils' ;
214import type { ServerComponentContext } from '../common/types' ;
225import { flushSafelyWithTimeout , waitUntil } from '../common/utils/responseEnd' ;
23- import { TRANSACTION_ATTR_SENTRY_TRACE_BACKFILL } from './span-attributes-with-logic-attached' ;
24- import { commonObjectToIsolationScope , commonObjectToPropagationContext } from './utils/tracingUtils' ;
6+ import { commonObjectToIsolationScope } from './utils/tracingUtils' ;
257
268/**
279 * Wraps an `app` directory server component with Sentry error instrumentation.
@@ -31,22 +13,13 @@ export function wrapServerComponentWithSentry<F extends (...args: any[]) => any>
3113 appDirComponent : F ,
3214 context : ServerComponentContext ,
3315) : F {
34- const { componentRoute, componentType } = context ;
3516 // Even though users may define server components as async functions, for the client bundles
3617 // Next.js will turn them into synchronous functions and it will transform any `await`s into instances of the `use`
3718 // hook. 🤯
3819 return new Proxy ( appDirComponent , {
3920 apply : ( originalFunction , thisArg , args ) => {
40- const requestTraceId = getActiveSpan ( ) ?. spanContext ( ) . traceId ;
4121 const isolationScope = commonObjectToIsolationScope ( context . headers ) ;
4222
43- const activeSpan = getActiveSpan ( ) ;
44- if ( activeSpan ) {
45- const rootSpan = getRootSpan ( activeSpan ) ;
46- const { scope } = getCapturedScopesOnSpan ( rootSpan ) ;
47- setCapturedScopesOnSpan ( rootSpan , scope ?? new Scope ( ) , isolationScope ) ;
48- }
49-
5023 const headersDict = context . headers ? winterCGHeadersToDict ( context . headers ) : undefined ;
5124
5225 isolationScope . setSDKProcessingMetadata ( {
@@ -56,72 +29,26 @@ export function wrapServerComponentWithSentry<F extends (...args: any[]) => any>
5629 } ) ;
5730
5831 return withIsolationScope ( isolationScope , ( ) => {
59- return withScope ( scope => {
60- scope . setTransactionName ( `${ componentType } Server Component (${ componentRoute } )` ) ;
61-
62- if ( process . env . NEXT_RUNTIME === 'edge' ) {
63- const propagationContext = commonObjectToPropagationContext (
64- context . headers ,
65- propagationContextFromHeaders ( headersDict ?. [ 'sentry-trace' ] , headersDict ?. [ 'baggage' ] ) ,
66- ) ;
67-
68- if ( requestTraceId ) {
69- propagationContext . traceId = requestTraceId ;
70- }
71-
72- scope . setPropagationContext ( propagationContext ) ;
73- }
74-
75- const activeSpan = getActiveSpan ( ) ;
76- if ( activeSpan ) {
77- const rootSpan = getRootSpan ( activeSpan ) ;
78- const sentryTrace = headersDict ?. [ 'sentry-trace' ] ;
79- if ( sentryTrace ) {
80- rootSpan . setAttribute ( TRANSACTION_ATTR_SENTRY_TRACE_BACKFILL , sentryTrace ) ;
81- }
82- }
83-
84- return startSpanManual (
85- {
86- op : 'function.nextjs' ,
87- name : `${ componentType } Server Component (${ componentRoute } )` ,
88- attributes : {
89- [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'component' ,
90- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.function.nextjs.server_component' ,
91- 'sentry.nextjs.ssr.function.type' : componentType ,
92- 'sentry.nextjs.ssr.function.route' : componentRoute ,
93- } ,
94- } ,
95- span => {
96- return handleCallbackErrors (
97- ( ) => originalFunction . apply ( thisArg , args ) ,
98- error => {
99- // When you read this code you might think: "Wait a minute, shouldn't we set the status on the root span too?"
100- // The answer is: "No." - The status of the root span is determined by whatever status code Next.js decides to put on the response.
101- if ( isNotFoundNavigationError ( error ) ) {
102- // We don't want to report "not-found"s
103- span . setStatus ( { code : SPAN_STATUS_ERROR , message : 'not_found' } ) ;
104- } else if ( isRedirectNavigationError ( error ) ) {
105- // We don't want to report redirects
106- span . setStatus ( { code : SPAN_STATUS_OK } ) ;
107- } else {
108- span . setStatus ( { code : SPAN_STATUS_ERROR , message : 'internal_error' } ) ;
109- captureException ( error , {
110- mechanism : {
111- handled : false ,
112- type : 'auto.function.nextjs.server_component' ,
113- } ,
114- } ) ;
115- }
32+ return handleCallbackErrors (
33+ ( ) => originalFunction . apply ( thisArg , args ) ,
34+ error => {
35+ if ( isNotFoundNavigationError ( error ) ) {
36+ // We don't want to report "not-found"s
37+ } else if ( isRedirectNavigationError ( error ) ) {
38+ // We don't want to report redirects
39+ } else {
40+ captureException ( error , {
41+ mechanism : {
42+ handled : false ,
43+ type : 'auto.function.nextjs.server_component' ,
11644 } ,
117- ( ) => {
118- span . end ( ) ;
119- waitUntil ( flushSafelyWithTimeout ( ) ) ;
120- } ,
121- ) ;
122- } ,
123- ) ;
124- } ) ;
45+ } ) ;
46+ }
47+ } ,
48+ ( ) => {
49+ waitUntil ( flushSafelyWithTimeout ( ) ) ;
50+ } ,
51+ ) ;
12552 } ) ;
12653 } ,
12754 } ) ;
0 commit comments