diff --git a/CHANGELOG.md b/CHANGELOG.md index 58dbc7ab8d..823c43f992 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ ### Internal - Add `InternalSentrySdk.captureEnvelopeNonTerminating` for hybrid SDKs (e.g. Flutter) so unhandled exceptions that don't terminate the process no longer end the session as `crashed` ([#5921](https://github.com/getsentry/sentry-java/pull/5921)) +- Add `InternalSentrySdk.updateSessionForDroppedEventNonTerminating` so hybrid SDKs can still update the session when an error is dropped by sampling ([#5990](https://github.com/getsentry/sentry-java/pull/5990)) ## 8.54.0 diff --git a/sentry-android-core/api/sentry-android-core.api b/sentry-android-core/api/sentry-android-core.api index f2162e72c5..40342d98a0 100644 --- a/sentry-android-core/api/sentry-android-core.api +++ b/sentry-android-core/api/sentry-android-core.api @@ -323,6 +323,7 @@ public final class io/sentry/android/core/InternalSentrySdk { public static fun getCurrentScope ()Lio/sentry/IScope; public static fun serializeScope (Landroid/content/Context;Lio/sentry/android/core/SentryAndroidOptions;Lio/sentry/IScope;)Ljava/util/Map; public static fun setTrace (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Double;Ljava/lang/Double;)V + public static fun updateSessionForDroppedEventNonTerminating (Z)V } public final class io/sentry/android/core/LoadClass : io/sentry/util/LoadClass { diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java b/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java index cb612cd7b9..a91225f32c 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java @@ -264,6 +264,23 @@ public static SentryId captureEnvelopeNonTerminating(final @NotNull byte[] envel return scopes.captureEnvelope(envelope); } + /** + * Session side effects of {@link #captureEnvelopeNonTerminating(byte[])} without sending the + * event. Hybrid SDKs should call this when an error is dropped by sampling. + * + *
Do not call this for events dropped by {@code beforeSend} or ignored exception types. + * + *
Persisting the session is a blocking disk write on the calling thread, so call this off the
+ * main thread as the hybrid SDKs do. It is synchronous on purpose: a deferred write would not be
+ * on disk yet if the process dies right after this returns.
+ *
+ * @param crashed {@code true} if the dropped error was unhandled ({@code
+ * mechanism.handled=false})
+ */
+ public static void updateSessionForDroppedEventNonTerminating(final boolean crashed) {
+ updateSessionNonTerminating(crashed);
+ }
+
/**
* Flags the current session for a non-terminating hybrid error and persists it before returning,
* so the marker survives an immediate process death.
diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt
index 88b54ce7c8..870b71855f 100644
--- a/sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt
+++ b/sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt
@@ -612,6 +612,86 @@ class InternalSentrySdkTest {
assertThat(activeSession.get().sessionId).isNotEqualTo(oldSid)
}
+ @Test
+ fun `updateSessionForDroppedEventNonTerminating flags an unhandled error without sending an envelope`() {
+ val fixture = Fixture()
+ fixture.init(context)
+
+ val originalSid = AtomicReference