feat(tracing): Wrap Expo Router push, replace, navigate, back, dismiss in addition to prefetch
#6221
3 issues
find-bugs: Found 3 issues (2 medium, 1 low)
Medium
Concrete pathname in object-form href bypasses `sendDefaultPii` gate, leaking PII in breadcrumbs and spans - `packages/core/src/js/tracing/expoRouter.ts:36`
Object hrefs like router.push({ pathname: '/users/42' }) always produce concretePathname: false, so the PII guard (parsed.concretePathname && !sendPii) is never triggered and the concrete pathname is emitted in breadcrumb messages, span names, and route.name attributes even when sendDefaultPii is false.
Stale pending navigation state incorrectly attributes unrelated spans - `packages/core/src/js/tracing/pendingExpoRouterNavigation.ts:26-33`
If a wrapped method like back() or dismiss() succeeds without actually triggering a React Navigation idle span (e.g. back() with an empty history stack), pending is never consumed and will be incorrectly attributed to the next unrelated idle navigation span via navigation.method.
Also found at:
packages/core/src/js/tracing/reactnavigation.ts:455-458packages/core/src/js/tracing/reactnavigation.ts:30packages/core/test/tracing/expoRouter.test.ts:382-390
Low
Pending Expo Router navigation consumed but silently dropped when span creation returns undefined - `packages/core/src/js/tracing/reactnavigation.ts:455-458`
consumePendingExpoRouterNavigation() (line 455) is called unconditionally, but startGenericIdleNavigationSpan returns undefined when there is no Sentry client (span.ts line 59โ61); the subsequent guard if (pendingExpoRouter && latestNavigationSpan) then fails, so the value is consumed and lost with no attribution applied.
โฑ 17m 10s ยท 1.9M in / 135.4k out ยท $4.19
Annotations
Check warning on line 36 in packages/core/src/js/tracing/expoRouter.ts
sentry-warden / warden: find-bugs
Concrete pathname in object-form href bypasses `sendDefaultPii` gate, leaking PII in breadcrumbs and spans
Object hrefs like `router.push({ pathname: '/users/42' })` always produce `concretePathname: false`, so the PII guard (`parsed.concretePathname && !sendPii`) is never triggered and the concrete pathname is emitted in breadcrumb messages, span names, and `route.name` attributes even when `sendDefaultPii` is `false`.
Check warning on line 33 in packages/core/src/js/tracing/pendingExpoRouterNavigation.ts
sentry-warden / warden: find-bugs
Stale pending navigation state incorrectly attributes unrelated spans
If a wrapped method like `back()` or `dismiss()` succeeds without actually triggering a React Navigation idle span (e.g. `back()` with an empty history stack), `pending` is never consumed and will be incorrectly attributed to the next unrelated idle navigation span via `navigation.method`.
Check warning on line 458 in packages/core/src/js/tracing/reactnavigation.ts
sentry-warden / warden: find-bugs
[JU4-MKG] Stale pending navigation state incorrectly attributes unrelated spans (additional location)
If a wrapped method like `back()` or `dismiss()` succeeds without actually triggering a React Navigation idle span (e.g. `back()` with an empty history stack), `pending` is never consumed and will be incorrectly attributed to the next unrelated idle navigation span via `navigation.method`.
Check warning on line 30 in packages/core/src/js/tracing/reactnavigation.ts
sentry-warden / warden: find-bugs
[JU4-MKG] Stale pending navigation state incorrectly attributes unrelated spans (additional location)
If a wrapped method like `back()` or `dismiss()` succeeds without actually triggering a React Navigation idle span (e.g. `back()` with an empty history stack), `pending` is never consumed and will be incorrectly attributed to the next unrelated idle navigation span via `navigation.method`.
Check warning on line 390 in packages/core/test/tracing/expoRouter.test.ts
sentry-warden / warden: find-bugs
[JU4-MKG] Stale pending navigation state incorrectly attributes unrelated spans (additional location)
If a wrapped method like `back()` or `dismiss()` succeeds without actually triggering a React Navigation idle span (e.g. `back()` with an empty history stack), `pending` is never consumed and will be incorrectly attributed to the next unrelated idle navigation span via `navigation.method`.