diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f52f86acb..bfae01def1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Fix duplicate error reporting on iOS with New Architecture ([#5532](https://github.com/getsentry/sentry-react-native/pull/5532)) - Fix for missing `replay_id` from metrics ([#5483](https://github.com/getsentry/sentry-react-native/pull/5483)) - Skip span ID check when standalone mode is enabled ([#5493](https://github.com/getsentry/sentry-react-native/pull/5493)) +- Fix traces not always being attached to replays with errors ([#5538](https://github.com/getsentry/sentry-react-native/pull/5538)) ### Dependencies diff --git a/packages/core/src/js/replay/mobilereplay.ts b/packages/core/src/js/replay/mobilereplay.ts index 293a14ea5d..437df76d3c 100644 --- a/packages/core/src/js/replay/mobilereplay.ts +++ b/packages/core/src/js/replay/mobilereplay.ts @@ -216,6 +216,12 @@ export const mobileReplayIntegration = (initOptions: MobileReplayOptions = defau debug.log( `[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} Captured recording replay ${replayId} for event ${event.event_id}.`, ); + // Add replay_id to error event contexts to link replays to events/traces + event.contexts = event.contexts || {}; + event.contexts.replay = { + ...event.contexts.replay, + replay_id: replayId, + }; } else { // Check if there's an ongoing recording and update cache if found const recordingReplayId = NATIVE.getCurrentReplayId(); @@ -224,6 +230,12 @@ export const mobileReplayIntegration = (initOptions: MobileReplayOptions = defau debug.log( `[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} assign already recording replay ${recordingReplayId} for event ${event.event_id}.`, ); + // Add replay_id to error event contexts to link replays to events/traces + event.contexts = event.contexts || {}; + event.contexts.replay = { + ...event.contexts.replay, + replay_id: recordingReplayId, + }; } else { updateCachedReplayId(null); debug.log(`[Sentry] ${MOBILE_REPLAY_INTEGRATION_NAME} not sampled for event ${event.event_id}.`); diff --git a/packages/core/test/replay/mobilereplay.test.ts b/packages/core/test/replay/mobilereplay.test.ts index aa76c65a36..eadbc0ac21 100644 --- a/packages/core/test/replay/mobilereplay.test.ts +++ b/packages/core/test/replay/mobilereplay.test.ts @@ -258,6 +258,25 @@ describe('Mobile Replay Integration', () => { expect(mockCaptureReplay).toHaveBeenCalled(); }); + + it('should add replay context to error events when replay is captured', async () => { + const integration = mobileReplayIntegration(); + const replayId = 'test-replay-id'; + mockCaptureReplay.mockResolvedValue(replayId); + + const event: Event = { + event_id: 'test-event-id', + exception: { + values: [{ type: 'Error', value: 'Test error' }], + }, + }; + const hint: EventHint = {}; + + if (integration.processEvent) { + const processedEvent = await integration.processEvent(event, hint); + expect(processedEvent.contexts?.replay?.replay_id).toBe(replayId); + } + }); }); describe('platform checks', () => {