feat(tracing): Correlate deep links with the navigation they trigger#6264
2 issues
find-bugs: Found 2 issues (2 medium)
Medium
Warm-open deep link can be consumed by a stale prior navigation span, leaving the triggered navigation span untagged - `packages/core/src/js/integrations/deeplink.ts:111-115`
handleLateDeepLink in reactnavigation.ts is invoked synchronously for every deep link via the registered pendingDeepLink listener, including warm-open url events. It picks latestNavigationSpan ?? lastIdleNavSpan. After a completed navigation latestNavigationSpan is undefined, so it falls back to lastIdleNavSpan, which is never cleared and keeps pointing at the previous screen's idle span. If that span is still recording (within its 1s idle timeout), the listener tags the previous span and returns true, so setPendingDeepLink never stores the URL. The navigation actually triggered by the deep link is then created moments later and finds nothing to consume in updateLatestNavigationSpanWithCurrentRoute, leaving it untagged while the wrong span carries navigation.trigger=deeplink.
Also found at:
packages/core/src/js/tracing/reactnavigation.ts:250-257packages/core/src/js/tracing/reactnavigation.ts:505packages/core/test/tracing/reactnavigation.test.ts:495-508
Stale pending deep link leaks to the wrong navigation span when `handleLateDeepLink` tags a span - `packages/core/src/js/tracing/reactnavigation.ts:768-770`
When applyPendingDeepLinkToSpan short-circuits because the span is already in taggedDeepLinkSpans, it returns early without calling consumePendingDeepLink, leaving any previously-stored pending link in the slot. A subsequent navigation's applyPendingDeepLinkToSpan call then consumes and applies the stale link, attributing the wrong URL to an unrelated span.
Also found at:
packages/core/src/js/tracing/reactnavigation.ts:606
⏱ 21m 46s · 3.6M in / 211.8k out · $6.83
Annotations
Check warning on line 115 in packages/core/src/js/integrations/deeplink.ts
sentry-warden / warden: find-bugs
Warm-open deep link can be consumed by a stale prior navigation span, leaving the triggered navigation span untagged
`handleLateDeepLink` in `reactnavigation.ts` is invoked synchronously for every deep link via the registered pendingDeepLink listener, including warm-open `url` events. It picks `latestNavigationSpan ?? lastIdleNavSpan`. After a completed navigation `latestNavigationSpan` is `undefined`, so it falls back to `lastIdleNavSpan`, which is never cleared and keeps pointing at the previous screen's idle span. If that span is still recording (within its 1s idle timeout), the listener tags the *previous* span and returns `true`, so `setPendingDeepLink` never stores the URL. The navigation actually triggered by the deep link is then created moments later and finds nothing to consume in `updateLatestNavigationSpanWithCurrentRoute`, leaving it untagged while the wrong span carries `navigation.trigger=deeplink`.
Check warning on line 257 in packages/core/src/js/tracing/reactnavigation.ts
sentry-warden / warden: find-bugs
[FBE-RE4] Warm-open deep link can be consumed by a stale prior navigation span, leaving the triggered navigation span untagged (additional location)
`handleLateDeepLink` in `reactnavigation.ts` is invoked synchronously for every deep link via the registered pendingDeepLink listener, including warm-open `url` events. It picks `latestNavigationSpan ?? lastIdleNavSpan`. After a completed navigation `latestNavigationSpan` is `undefined`, so it falls back to `lastIdleNavSpan`, which is never cleared and keeps pointing at the previous screen's idle span. If that span is still recording (within its 1s idle timeout), the listener tags the *previous* span and returns `true`, so `setPendingDeepLink` never stores the URL. The navigation actually triggered by the deep link is then created moments later and finds nothing to consume in `updateLatestNavigationSpanWithCurrentRoute`, leaving it untagged while the wrong span carries `navigation.trigger=deeplink`.
Check warning on line 505 in packages/core/src/js/tracing/reactnavigation.ts
sentry-warden / warden: find-bugs
[FBE-RE4] Warm-open deep link can be consumed by a stale prior navigation span, leaving the triggered navigation span untagged (additional location)
`handleLateDeepLink` in `reactnavigation.ts` is invoked synchronously for every deep link via the registered pendingDeepLink listener, including warm-open `url` events. It picks `latestNavigationSpan ?? lastIdleNavSpan`. After a completed navigation `latestNavigationSpan` is `undefined`, so it falls back to `lastIdleNavSpan`, which is never cleared and keeps pointing at the previous screen's idle span. If that span is still recording (within its 1s idle timeout), the listener tags the *previous* span and returns `true`, so `setPendingDeepLink` never stores the URL. The navigation actually triggered by the deep link is then created moments later and finds nothing to consume in `updateLatestNavigationSpanWithCurrentRoute`, leaving it untagged while the wrong span carries `navigation.trigger=deeplink`.
Check warning on line 508 in packages/core/test/tracing/reactnavigation.test.ts
sentry-warden / warden: find-bugs
[FBE-RE4] Warm-open deep link can be consumed by a stale prior navigation span, leaving the triggered navigation span untagged (additional location)
`handleLateDeepLink` in `reactnavigation.ts` is invoked synchronously for every deep link via the registered pendingDeepLink listener, including warm-open `url` events. It picks `latestNavigationSpan ?? lastIdleNavSpan`. After a completed navigation `latestNavigationSpan` is `undefined`, so it falls back to `lastIdleNavSpan`, which is never cleared and keeps pointing at the previous screen's idle span. If that span is still recording (within its 1s idle timeout), the listener tags the *previous* span and returns `true`, so `setPendingDeepLink` never stores the URL. The navigation actually triggered by the deep link is then created moments later and finds nothing to consume in `updateLatestNavigationSpanWithCurrentRoute`, leaving it untagged while the wrong span carries `navigation.trigger=deeplink`.
Check warning on line 770 in packages/core/src/js/tracing/reactnavigation.ts
sentry-warden / warden: find-bugs
Stale pending deep link leaks to the wrong navigation span when `handleLateDeepLink` tags a span
When `applyPendingDeepLinkToSpan` short-circuits because the span is already in `taggedDeepLinkSpans`, it returns early without calling `consumePendingDeepLink`, leaving any previously-stored pending link in the slot. A subsequent navigation's `applyPendingDeepLinkToSpan` call then consumes and applies the stale link, attributing the wrong URL to an unrelated span.
Check warning on line 606 in packages/core/src/js/tracing/reactnavigation.ts
sentry-warden / warden: find-bugs
[4Z3-NVS] Stale pending deep link leaks to the wrong navigation span when `handleLateDeepLink` tags a span (additional location)
When `applyPendingDeepLinkToSpan` short-circuits because the span is already in `taggedDeepLinkSpans`, it returns early without calling `consumePendingDeepLink`, leaving any previously-stored pending link in the slot. A subsequent navigation's `applyPendingDeepLinkToSpan` call then consumes and applies the stale link, attributing the wrong URL to an unrelated span.