From 6ef7deb5181aa08f156cb5bd8f8783625a8daeb1 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Thu, 9 Jan 2025 16:32:35 +0100 Subject: [PATCH] ref(browser): Improve active span handling for `browserTracingIntegration` --- .../src/tracing/browserTracingIntegration.ts | 44 +++++++++++-------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/packages/browser/src/tracing/browserTracingIntegration.ts b/packages/browser/src/tracing/browserTracingIntegration.ts index 500521e29961..f4ab605be9c2 100644 --- a/packages/browser/src/tracing/browserTracingIntegration.ts +++ b/packages/browser/src/tracing/browserTracingIntegration.ts @@ -16,9 +16,9 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, TRACING_DEFAULTS, + addNonEnumerableProperty, browserPerformanceTimeOrigin, generateTraceId, - getActiveSpan, getClient, getCurrentScope, getDynamicSamplingContextFromSpan, @@ -247,7 +247,7 @@ export const browserTracingIntegration = ((_options: Partial { _collectWebVitals(); addPerformanceEntries(span, { recordClsOnPageloadSpan: !enableStandaloneClsSpans }); + setActiveIdleSpan(client, undefined); }, }); + setActiveIdleSpan(client, idleSpan); function emitFinish(): void { if (optionalWindowDocument && ['interactive', 'complete'].includes(optionalWindowDocument.readyState)) { @@ -291,17 +293,16 @@ export const browserTracingIntegration = ((_options: Partial { const op = 'ui.action.click'; - const activeSpan = getActiveSpan(); - const rootSpan = activeSpan && getRootSpan(activeSpan); - if (rootSpan) { - const currentRootSpanOp = spanToJSON(rootSpan).op; + const activeIdleSpan = getActiveIdleSpan(client); + if (activeIdleSpan) { + const currentRootSpanOp = spanToJSON(activeIdleSpan).op; if (['navigation', 'pageload'].includes(currentRootSpanOp as string)) { DEBUG_BUILD && logger.warn(`[Tracing] Did not create ${op} span because a pageload or navigation span is in progress.`); @@ -537,3 +533,13 @@ function registerInteractionListener( addEventListener('click', registerInteractionTransaction, { once: false, capture: true }); } } + +// We store the active idle span on the client object, so we can access it from exported functions +const ACTIVE_IDLE_SPAN_PROPERTY = '_sentry_idleSpan'; +function getActiveIdleSpan(client: Client): Span | undefined { + return (client as { [ACTIVE_IDLE_SPAN_PROPERTY]?: Span })[ACTIVE_IDLE_SPAN_PROPERTY]; +} + +function setActiveIdleSpan(client: Client, span: Span | undefined): void { + addNonEnumerableProperty(client, ACTIVE_IDLE_SPAN_PROPERTY, span); +}