8
8
getRootSpan ,
9
9
handleCallbackErrors ,
10
10
setHttpStatus ,
11
+ spanToJSON ,
11
12
startSpan ,
12
13
} from '@sentry/core' ;
13
14
import type { Span } from '@sentry/types' ;
@@ -24,32 +25,41 @@ function startOrUpdateSpan(spanName: string, cb: (rootSpan: Span) => Promise<Res
24
25
const activeSpan = getActiveSpan ( ) ;
25
26
const rootSpan = activeSpan && getRootSpan ( activeSpan ) ;
26
27
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)
34
32
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 ) {
37
40
return startSpan (
38
41
{
39
- op : 'http.server' ,
40
42
name : spanName ,
41
43
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,
50
45
} ,
46
+ cb ,
51
47
) ;
52
48
}
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 ) ;
53
63
}
54
64
55
65
/**
0 commit comments