1
- import type { Context , Span , SpanOptions , Tracer , TracerProvider } from '@opentelemetry/api' ;
2
- import { ProxyTracerProvider , trace } from '@opentelemetry/api' ;
1
+ import type { Context , ProxyTracerProvider , Span , SpanOptions , Tracer , TracerProvider } from '@opentelemetry/api' ;
2
+ import { trace } from '@opentelemetry/api' ;
3
3
import { startInactiveSpan , startSpanManual } from '@sentry/core' ;
4
4
5
5
/**
6
6
* Set up a mock OTEL tracer to allow inter-op with OpenTelemetry emitted spans.
7
7
* This is not perfect but handles easy/common use cases.
8
8
*/
9
9
export function setupOpenTelemetryTracer ( ) : void {
10
- const current = trace . getTracerProvider ( ) ;
11
- const delegate = current instanceof ProxyTracerProvider ? current . getDelegate ( ) : current ;
12
- trace . setGlobalTracerProvider ( new SentryCloudflareTraceProvider ( delegate ) ) ;
10
+ const result = trace . setGlobalTracerProvider ( new SentryCloudflareTraceProvider ( ) ) ;
11
+ if ( result ) {
12
+ return ;
13
+ }
14
+ const current = trace . getTracerProvider ( ) as ProxyTracerProvider ;
15
+ current . setDelegate ( new SentryCloudflareTraceProvider ( current . getDelegate ( ) ) ) ;
13
16
}
14
17
15
18
class SentryCloudflareTraceProvider implements TracerProvider {
16
19
private readonly _tracers : Map < string , Tracer > = new Map ( ) ;
17
20
18
- public constructor ( private readonly _provider : TracerProvider ) { }
21
+ public constructor ( private readonly _provider ? : TracerProvider ) { }
19
22
20
23
public getTracer ( name : string , version ?: string , options ?: { schemaUrl ?: string } ) : Tracer {
21
24
const key = `${ name } @${ version || '' } :${ options ?. schemaUrl || '' } ` ;
22
25
if ( ! this . _tracers . has ( key ) ) {
23
- const tracer = this . _provider . getTracer ( key , version , options ) ;
26
+ const tracer = this . _provider ? .getTracer ?. ( key , version , options ) ;
24
27
this . _tracers . set ( key , new SentryCloudflareTracer ( tracer ) ) ;
25
28
}
26
29
@@ -30,9 +33,9 @@ class SentryCloudflareTraceProvider implements TracerProvider {
30
33
}
31
34
32
35
class SentryCloudflareTracer implements Tracer {
33
- public constructor ( private readonly _tracer : Tracer ) { }
36
+ public constructor ( private readonly _tracer ? : Tracer ) { }
34
37
public startSpan ( name : string , options ?: SpanOptions ) : Span {
35
- const topSpan = this . _tracer . startSpan ( name , options ) ;
38
+ const topSpan = this . _tracer ? .startSpan ?. ( name , options ) ;
36
39
const sentrySpan = startInactiveSpan ( {
37
40
name,
38
41
...options ,
@@ -41,7 +44,18 @@ class SentryCloudflareTracer implements Tracer {
41
44
'sentry.cloudflare_tracer' : true ,
42
45
} ,
43
46
} ) ;
47
+ if ( ! topSpan ) {
48
+ return sentrySpan ;
49
+ }
44
50
return new Proxy ( sentrySpan , {
51
+ set : ( target , p , newValue , receiver ) => {
52
+ try {
53
+ Reflect . set ( topSpan , p , newValue , receiver ) ;
54
+ } catch {
55
+ //
56
+ }
57
+ return Reflect . set ( target , p , newValue ) ;
58
+ } ,
45
59
get : ( target , p ) => {
46
60
const propertyValue = Reflect . get ( target , p ) ;
47
61
if ( typeof propertyValue !== 'function' ) {
@@ -55,7 +69,7 @@ class SentryCloudflareTracer implements Tracer {
55
69
apply : ( target , thisArg , argArray ) => {
56
70
try {
57
71
Reflect . apply ( proxyTo , topSpan , argArray ) ;
58
- } catch ( e ) {
72
+ } catch {
59
73
//
60
74
}
61
75
return Reflect . apply ( target , thisArg , argArray ) ;
0 commit comments