Skip to content

Commit 7547547

Browse files
committed
ref(browser): Improve active span handling for browserTracingIntegration
1 parent 6779dfe commit 7547547

File tree

1 file changed

+21
-15
lines changed

1 file changed

+21
-15
lines changed

packages/browser/src/tracing/browserTracingIntegration.ts

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ import {
1616
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
1717
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
1818
TRACING_DEFAULTS,
19+
addNonEnumerableProperty,
1920
browserPerformanceTimeOrigin,
2021
generateTraceId,
21-
getActiveSpan,
2222
getClient,
2323
getCurrentScope,
2424
getDynamicSamplingContextFromSpan,
@@ -246,7 +246,7 @@ export const browserTracingIntegration = ((_options: Partial<BrowserTracingOptio
246246
};
247247

248248
/** Create routing idle transaction. */
249-
function _createRouteSpan(client: Client, startSpanOptions: StartSpanOptions): Span {
249+
function _createRouteSpan(client: Client, startSpanOptions: StartSpanOptions): void {
250250
const isPageloadTransaction = startSpanOptions.op === 'pageload';
251251

252252
const finalStartSpanOptions: StartSpanOptions = beforeStartSpan
@@ -291,7 +291,8 @@ export const browserTracingIntegration = ((_options: Partial<BrowserTracingOptio
291291
emitFinish();
292292
}
293293

294-
return idleSpan;
294+
// A trace should to stay the consistent over the entire time span of one route.
295+
setActiveIdleSpan(client, idleSpan);
295296
}
296297

297298
return {
@@ -315,7 +316,7 @@ export const browserTracingIntegration = ((_options: Partial<BrowserTracingOptio
315316

316317
maybeEndActiveSpan();
317318

318-
activeSpan = _createRouteSpan(client, {
319+
_createRouteSpan(client, {
319320
op: 'navigation',
320321
...startSpanOptions,
321322
});
@@ -333,7 +334,7 @@ export const browserTracingIntegration = ((_options: Partial<BrowserTracingOptio
333334
const propagationContext = propagationContextFromHeaders(sentryTrace, baggage);
334335
getCurrentScope().setPropagationContext(propagationContext);
335336

336-
activeSpan = _createRouteSpan(client, {
337+
_createRouteSpan(client, {
337338
op: 'pageload',
338339
...startSpanOptions,
339340
});
@@ -408,7 +409,7 @@ export const browserTracingIntegration = ((_options: Partial<BrowserTracingOptio
408409
}
409410

410411
if (enableInteractions) {
411-
registerInteractionListener(idleTimeout, finalTimeout, childSpanTimeout, latestRoute);
412+
registerInteractionListener(client, idleTimeout, finalTimeout, childSpanTimeout, latestRoute);
412413
}
413414

414415
if (enableInp) {
@@ -440,12 +441,9 @@ export function startBrowserTracingPageLoadSpan(
440441
traceOptions?: { sentryTrace?: string | undefined; baggage?: string | undefined },
441442
): Span | undefined {
442443
client.emit('startPageLoadSpan', spanOptions, traceOptions);
443-
444444
getCurrentScope().setTransactionName(spanOptions.name);
445445

446-
const span = getActiveSpan();
447-
const op = span && spanToJSON(span).op;
448-
return op === 'pageload' ? span : undefined;
446+
return getActiveIdleSpan(client);
449447
}
450448

451449
/**
@@ -460,9 +458,7 @@ export function startBrowserTracingNavigationSpan(client: Client, spanOptions: S
460458

461459
getCurrentScope().setTransactionName(spanOptions.name);
462460

463-
const span = getActiveSpan();
464-
const op = span && spanToJSON(span).op;
465-
return op === 'navigation' ? span : undefined;
461+
return getActiveIdleSpan(client);
466462
}
467463

468464
/** Returns the value of a meta tag */
@@ -479,6 +475,7 @@ export function getMetaContent(metaName: string): string | undefined {
479475

480476
/** Start listener for interaction transactions */
481477
function registerInteractionListener(
478+
client: Client,
482479
idleTimeout: BrowserTracingOptions['idleTimeout'],
483480
finalTimeout: BrowserTracingOptions['finalTimeout'],
484481
childSpanTimeout: BrowserTracingOptions['childSpanTimeout'],
@@ -494,8 +491,7 @@ function registerInteractionListener(
494491
const registerInteractionTransaction = (): void => {
495492
const op = 'ui.action.click';
496493

497-
const activeSpan = getActiveSpan();
498-
const rootSpan = activeSpan && getRootSpan(activeSpan);
494+
const rootSpan = getActiveIdleSpan(client);
499495
if (rootSpan) {
500496
const currentRootSpanOp = spanToJSON(rootSpan).op;
501497
if (['navigation', 'pageload'].includes(currentRootSpanOp as string)) {
@@ -536,3 +532,13 @@ function registerInteractionListener(
536532
addEventListener('click', registerInteractionTransaction, { once: false, capture: true });
537533
}
538534
}
535+
536+
// We store the active idle span on the client object, so we can access it from exported functions
537+
const ACTIVE_IDLE_SPAN_PROPERTY = '_sentry_idleSpan';
538+
function getActiveIdleSpan(client: Client): Span | undefined {
539+
return (client as { [ACTIVE_IDLE_SPAN_PROPERTY]?: Span })[ACTIVE_IDLE_SPAN_PROPERTY];
540+
}
541+
542+
function setActiveIdleSpan(client: Client, span: Span): void {
543+
addNonEnumerableProperty(client, ACTIVE_IDLE_SPAN_PROPERTY, span);
544+
}

0 commit comments

Comments
 (0)