feat(tracing): Add extend app start API for standalone app start#6392
feat(tracing): Add extend app start API for standalone app start#6392antonis wants to merge 8 commits into
2 issues
code-review: Found 2 issues (1 medium, 1 low)
Medium
`finalizeStandaloneAppStart` loses the trimmed end time when `appStartEndData` is unset - `packages/core/etc/sentry-react-native.api.md:308`
When extendAppStart() is used in standalone mode without Sentry.wrap() or appLoaded(), appStartEndData is null at finalization time. The guard if (appStartEndData && trimmedEndMs) on line 857 of appStart.ts then skips the mutation that propagates trimmedEndMs into appStartEndData. As a result, attachAppStartToTransactionEvent falls back to getBundleStartTimestampMs() and overwrites event.timestamp with the bundle-start time, nullifying the extension and producing an incorrect (shorter) measurement and transaction end — defeating the purpose of the API for users who don't use wrap(). Note that the normal captureStandaloneAppStart path does self-heal by calling _setAppStartEndData, but the extend/finalize path has no equivalent, so it depends solely on wrap()/appLoaded() having run.
Also found at:
packages/core/src/js/tracing/integrations/appStart.ts:47
Low
runApplication reset during in-flight finalizeStandaloneAppStart poisons appStartDataFlushed for the next run - `packages/core/src/js/tracing/integrations/appStart.ts:406-407`
Resetting extendedAppStartFinalized = false (and appStartDataFlushed = false) synchronously in the runApplication handler while finalizeStandaloneAppStart is still awaiting NATIVE.fetchNativeAppStart() can cause the resumed finalization to re-set appStartDataFlushed = true against the new run's state, silently dropping the next run's app start capture. Consider checking a generation counter or snapshotting key state into the async closure before yielding.
⏱ 17m 1s · 2.5M in / 136.9k out · $4.56
Annotations
Check warning on line 308 in packages/core/etc/sentry-react-native.api.md
sentry-warden / warden: code-review
`finalizeStandaloneAppStart` loses the trimmed end time when `appStartEndData` is unset
When `extendAppStart()` is used in standalone mode without `Sentry.wrap()` or `appLoaded()`, `appStartEndData` is null at finalization time. The guard `if (appStartEndData && trimmedEndMs)` on line 857 of `appStart.ts` then skips the mutation that propagates `trimmedEndMs` into `appStartEndData`. As a result, `attachAppStartToTransactionEvent` falls back to `getBundleStartTimestampMs()` and overwrites `event.timestamp` with the bundle-start time, nullifying the extension and producing an incorrect (shorter) measurement and transaction end — defeating the purpose of the API for users who don't use `wrap()`. Note that the normal `captureStandaloneAppStart` path does self-heal by calling `_setAppStartEndData`, but the extend/finalize path has no equivalent, so it depends solely on `wrap()`/`appLoaded()` having run.
Check warning on line 47 in packages/core/src/js/tracing/integrations/appStart.ts
sentry-warden / warden: code-review
[3S5-9QG] `finalizeStandaloneAppStart` loses the trimmed end time when `appStartEndData` is unset (additional location)
When `extendAppStart()` is used in standalone mode without `Sentry.wrap()` or `appLoaded()`, `appStartEndData` is null at finalization time. The guard `if (appStartEndData && trimmedEndMs)` on line 857 of `appStart.ts` then skips the mutation that propagates `trimmedEndMs` into `appStartEndData`. As a result, `attachAppStartToTransactionEvent` falls back to `getBundleStartTimestampMs()` and overwrites `event.timestamp` with the bundle-start time, nullifying the extension and producing an incorrect (shorter) measurement and transaction end — defeating the purpose of the API for users who don't use `wrap()`. Note that the normal `captureStandaloneAppStart` path does self-heal by calling `_setAppStartEndData`, but the extend/finalize path has no equivalent, so it depends solely on `wrap()`/`appLoaded()` having run.