Skip to content

Commit 0cb493b

Browse files
committed
Reinstate isolation scope pinning in startActiveSpan
1 parent a84b2a0 commit 0cb493b

1 file changed

Lines changed: 11 additions & 1 deletion

File tree

packages/opentelemetry/src/tracer.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
_INTERNAL_setSpanForScope,
77
_INTERNAL_startInactiveSpan,
88
addChildSpanToSpan,
9+
getCapturedScopesOnSpan,
910
getCurrentScope,
1011
getDynamicSamplingContextFromSpan,
1112
getIsolationScope,
@@ -18,6 +19,7 @@ import {
1819
} from '@sentry/core';
1920
import type { Span, SpanAttributes, SpanLink } from '@sentry/core';
2021
import { applyOtelSpanData, applyOtelSpanKind } from './applyOtelSpanData';
22+
import { SENTRY_FORK_SET_ISOLATION_SCOPE_CONTEXT_KEY } from './constants';
2123
import { getSamplingDecision } from './utils/getSamplingDecision';
2224

2325
export class SentryTracer implements Tracer {
@@ -66,7 +68,15 @@ export class SentryTracer implements Tracer {
6668
) as F;
6769

6870
const span = this.startSpan(name, options, ctx);
69-
const ctxWithSpan = trace.setSpan(ctx, span);
71+
let ctxWithSpan = trace.setSpan(ctx, span);
72+
73+
// Run the span's callback under the isolation scope captured when the span was created, so scope state
74+
// used or set during the span (tags, breadcrumbs, captured errors) belongs to that span and stays
75+
// isolated from other concurrent work. Without this it can land on a different isolation scope.
76+
const capturedIsolationScope = getCapturedScopesOnSpan(span as unknown as Span).isolationScope;
77+
if (capturedIsolationScope) {
78+
ctxWithSpan = ctxWithSpan.setValue(SENTRY_FORK_SET_ISOLATION_SCOPE_CONTEXT_KEY, capturedIsolationScope);
79+
}
7080

7181
return context.with(ctxWithSpan, () => {
7282
_INTERNAL_setSpanForScope(getCurrentScope(), span as unknown as Span);

0 commit comments

Comments
 (0)