88 getRootSpan ,
99 handleCallbackErrors ,
1010 setHttpStatus ,
11+ spanToJSON ,
1112 startSpan ,
1213} from '@sentry/core' ;
1314import type { Span } from '@sentry/types' ;
@@ -24,32 +25,41 @@ function startOrUpdateSpan(spanName: string, cb: (rootSpan: Span) => Promise<Res
2425 const activeSpan = getActiveSpan ( ) ;
2526 const rootSpan = activeSpan && getRootSpan ( activeSpan ) ;
2627
27- if ( rootSpan ) {
28- rootSpan . updateName ( spanName ) ;
29- rootSpan . setAttributes ( {
30- [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'route' ,
31- [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'http.server' ,
32- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.function.nextjs' ,
33- } ) ;
28+ // We have different possible scenarios here:
29+ // 1. If we have no root span, we just create a new span
30+ // 2. We have a root span that that we want to update here
31+ // 3. We have a root span that was already updated (e.g. if this is a nested call)
3432
35- return cb ( rootSpan ) ;
36- } else {
33+ const attributes = {
34+ [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'route' ,
35+ [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'http.server' ,
36+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.function.nextjs' ,
37+ } as const ;
38+
39+ if ( ! rootSpan ) {
3740 return startSpan (
3841 {
39- op : 'http.server' ,
4042 name : spanName ,
4143 forceTransaction : true ,
42- attributes : {
43- [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'route' ,
44- [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'http.server' ,
45- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.function.nextjs' ,
46- } ,
47- } ,
48- ( span : Span ) => {
49- return cb ( span ) ;
44+ attributes,
5045 } ,
46+ cb ,
5147 ) ;
5248 }
49+
50+ // If `op` is set, we assume this was already processed before
51+ // Probably this is a nested call, no need to update anything anymore
52+ // OR, if we don't have next.span_type, we don't know where this comes from and don't want to mess with it
53+ const existingAttributes = spanToJSON ( rootSpan ) . data || { } ;
54+ if ( existingAttributes [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] || ! existingAttributes [ 'next.span_type' ] ) {
55+ return cb ( rootSpan ) ;
56+ }
57+
58+ // Finally, we want to update the root span, as the ones generated by next are often not good enough for us
59+ rootSpan . updateName ( spanName ) ;
60+ rootSpan . setAttributes ( attributes ) ;
61+
62+ return cb ( rootSpan ) ;
5363}
5464
5565/**
0 commit comments