diff --git a/CHANGELOG.md b/CHANGELOG.md index 6528ac7c02..44bd1af87f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ ### Fixes - Session Replay: Fix first recording segment missing for replays in `buffer` mode ([#5753](https://github.com/getsentry/sentry-java/pull/5753)) +- Fix error-to-replay linkage in buffer mode ([#5754](https://github.com/getsentry/sentry-java/pull/5754)) - Fix main thread identification for tombstone (native crash) events ([#5742](https://github.com/getsentry/sentry-java/pull/5742)) ### Dependencies diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index c0b6fec780..00183bc9b3 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -37,6 +37,7 @@ public final class io/sentry/Baggage { public fun (Lio/sentry/Baggage;)V public fun (Lio/sentry/ILogger;)V public fun (Ljava/util/concurrent/ConcurrentHashMap;Ljava/lang/Double;Ljava/lang/Double;Ljava/lang/String;ZZLio/sentry/ILogger;)V + public fun forceSetReplayId (Lio/sentry/protocol/SentryId;)V public fun forceSetSampleRate (Ljava/lang/Double;)V public fun freeze ()V public static fun fromEvent (Lio/sentry/SentryBaseEvent;Ljava/lang/String;Lio/sentry/SentryOptions;)Lio/sentry/Baggage; diff --git a/sentry/src/main/java/io/sentry/Baggage.java b/sentry/src/main/java/io/sentry/Baggage.java index 4645df3f3a..9f0753f867 100644 --- a/sentry/src/main/java/io/sentry/Baggage.java +++ b/sentry/src/main/java/io/sentry/Baggage.java @@ -451,6 +451,19 @@ public void setReplayId(final @Nullable String replayId) { set(DSCKeys.REPLAY_ID, replayId); } + /** + * Sets replay_id on the baggage bypassing the freeze check. In buffer mode the replay_id is + * unknown when the baggage is frozen, so it must be injected after {@link + * ReplayController#captureReplay} sets it on scope. This mirrors the JS SDK's setReplayIdOnDynamicSamplingContext. + */ + @ApiStatus.Internal + public void forceSetReplayId(final @NotNull SentryId replayId) { + if (!SentryId.EMPTY_ID.equals(replayId)) { + keyValues.put(DSCKeys.REPLAY_ID, replayId.toString()); + } + } + @ApiStatus.Internal public @Nullable String getOrgId() { return get(DSCKeys.ORG_ID); diff --git a/sentry/src/main/java/io/sentry/SentryClient.java b/sentry/src/main/java/io/sentry/SentryClient.java index 02934b1ed7..b20734b29d 100644 --- a/sentry/src/main/java/io/sentry/SentryClient.java +++ b/sentry/src/main/java/io/sentry/SentryClient.java @@ -250,6 +250,18 @@ private boolean shouldApplyScopeData(final @NotNull CheckIn event, final @NotNul } if (shouldCaptureReplay) { options.getReplayController().captureReplay(event.isCrashed()); + if (scope != null) { + final @Nullable SentryId replayId = scope.getReplayId(); + if (replayId != null && !replayId.equals(SentryId.EMPTY_ID)) { + final @Nullable ITransaction transaction = scope.getTransaction(); + if (transaction != null) { + final @Nullable Baggage baggage = transaction.getSpanContext().getBaggage(); + if (baggage != null) { + baggage.forceSetReplayId(replayId); + } + } + } + } } }