From 259c87187c1abfccadbccfa2f61e938124f44922 Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Tue, 18 Jul 2023 09:18:51 +0200 Subject: [PATCH 1/5] Fix ensure session is updated using configureScope --- .../io/sentry/android/core/InternalSentrySdk.java | 2 +- .../io/sentry/android/core/InternalSentrySdkTest.kt | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) 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 bdc9f055e5..32fb0d8f23 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 @@ -181,7 +181,7 @@ private static Session updateSession( final @Nullable Session.State status, final boolean crashedOrErrored) { final @NotNull AtomicReference sessionRef = new AtomicReference<>(); - hub.withScope( + hub.configureScope( scope -> { final @Nullable Session session = scope.getSession(); if (session != null) { 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 2e0537365d..ba85423607 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 @@ -29,6 +29,7 @@ import org.mockito.kotlin.whenever import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.InputStreamReader +import java.util.concurrent.atomic.AtomicReference import kotlin.test.BeforeTest import kotlin.test.Test import kotlin.test.assertEquals @@ -251,20 +252,26 @@ class InternalSentrySdkTest { } ) - // then the session should be included val capturedEnvelope = fixture.capturedEnvelopes.first() val capturedEnvelopeItems = capturedEnvelope.items.toList() - // and it should contain the original event / attachment + // then it should contain the original event + session assertEquals(2, capturedEnvelopeItems.size) assertEquals(SentryItemType.Event, capturedEnvelopeItems[0].header.type) assertEquals(SentryItemType.Session, capturedEnvelopeItems[1].header.type) + // and then the sent session should be marked as crashed val capturedSession = fixture.options.serializer.deserialize( InputStreamReader(ByteArrayInputStream(capturedEnvelopeItems[1].data)), Session::class.java )!! - assertEquals(Session.State.Crashed, capturedSession.status) + + // and the local session should be marked as crashed too + val scopeRef = AtomicReference() + Sentry.configureScope { scope -> + scopeRef.set(scope) + } + assertEquals(Session.State.Crashed, scopeRef.get().session!!.status) } } From 6110b1ecd355ad0227c6cadab0ef181228952874 Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Tue, 18 Jul 2023 10:35:56 +0200 Subject: [PATCH 2/5] Add improvements based on PR comments --- .../android/core/InternalSentrySdk.java | 92 ++++++++++--------- .../android/core/InternalSentrySdkTest.kt | 5 +- 2 files changed, 51 insertions(+), 46 deletions(-) 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 32fb0d8f23..04d4f9fc7e 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 @@ -41,7 +41,8 @@ public final class InternalSentrySdk { @Nullable public static Scope getCurrentScope() { final @NotNull AtomicReference scopeRef = new AtomicReference<>(); - HubAdapter.getInstance().withScope(scopeRef::set); + //noinspection Convert2MethodRef + HubAdapter.getInstance().withScope(scope -> scopeRef.set(scope)); return scopeRef.get(); } @@ -53,22 +54,21 @@ public static Scope getCurrentScope() { * @param options Sentry Options * @param scope the scope * @return a map containing all relevant scope data (user, contexts, tags, extras, fingerprint, - * level, breadcrumbs) + * level, breadcrumbs) or null if the scope itself is null or serialization fails */ @NotNull public static Map serializeScope( final @NotNull Context context, final @NotNull SentryAndroidOptions options, final @Nullable Scope scope) { + final @NotNull Map data = new HashMap<>(); if (scope == null) { return data; } - - final @NotNull ILogger logger = options.getLogger(); - final @NotNull ObjectWriter writer = new MapObjectWriter(data); - try { + final @NotNull ILogger logger = options.getLogger(); + final @NotNull ObjectWriter writer = new MapObjectWriter(data); final @NotNull DeviceInfoUtil deviceInfoUtil = DeviceInfoUtil.getInstance(context, options); final @NotNull Device deviceInfo = deviceInfoUtil.collectDeviceInformation(true, true); @@ -114,7 +114,7 @@ public static Map serializeScope( writer.name("fingerprint").value(logger, scope.getFingerprint()); writer.name("level").value(logger, scope.getLevel()); writer.name("breadcrumbs").value(logger, scope.getBreadcrumbs()); - } catch (Exception e) { + } catch (Throwable e) { options.getLogger().log(SentryLevel.ERROR, "Could not serialize scope.", e); return new HashMap<>(); } @@ -124,54 +124,62 @@ public static Map serializeScope( /** * Captures the provided envelope. Compared to {@link IHub#captureEvent(SentryEvent)} this method - * - will not enrich events with additional data (e.g. scope) - will not execute beforeSend: it's - * up to the caller to take care of this - will not perform any sampling: it's up to the caller to - * take care of this - will enrich the envelope with a Session updates is applicable + *
+ * - will not enrich events with additional data (e.g. scope)
+ * - will not execute beforeSend: it's up to the caller to take care of this
+ * - will not perform any sampling: it's up to the caller to take care of this
+ * - will enrich the envelope with a Session update if applicable
* * @param envelopeData the serialized envelope data - * @return The Id (SentryId object) of the event - * @throws Exception In case the provided envelope could not be parsed / is invalid + * @return The Id (SentryId object) of the event, or null in case the envelope could not be + * captured */ - public static SentryId captureEnvelope(final @NotNull byte[] envelopeData) throws Exception { + @Nullable + public static SentryId captureEnvelope(final @NotNull byte[] envelopeData) { final @NotNull IHub hub = HubAdapter.getInstance(); final @NotNull SentryOptions options = hub.getOptions(); - final @NotNull ISerializer serializer = options.getSerializer(); - final @Nullable SentryEnvelope envelope = - options.getEnvelopeReader().read(new ByteArrayInputStream(envelopeData)); - if (envelope == null) { - throw new IllegalArgumentException("Envelope could not be read"); - } + try { + final @NotNull ISerializer serializer = options.getSerializer(); + final @Nullable SentryEnvelope envelope = + options.getEnvelopeReader().read(new ByteArrayInputStream(envelopeData)); + if (envelope == null) { + return null; + } - final @NotNull List envelopeItems = new ArrayList<>(); + final @NotNull List envelopeItems = new ArrayList<>(); - // determine session state based on events inside envelope - @Nullable Session.State status = null; - boolean crashedOrErrored = false; - for (SentryEnvelopeItem item : envelope.getItems()) { - envelopeItems.add(item); + // determine session state based on events inside envelope + @Nullable Session.State status = null; + boolean crashedOrErrored = false; + for (SentryEnvelopeItem item : envelope.getItems()) { + envelopeItems.add(item); - final SentryEvent event = item.getEvent(serializer); - if (event != null) { - if (event.isCrashed()) { - status = Session.State.Crashed; - } - if (event.isCrashed() || event.isErrored()) { - crashedOrErrored = true; + final SentryEvent event = item.getEvent(serializer); + if (event != null) { + if (event.isCrashed()) { + status = Session.State.Crashed; + } + if (event.isCrashed() || event.isErrored()) { + crashedOrErrored = true; + } } } - } - // update session and add it to envelope if necessary - final @Nullable Session session = updateSession(hub, options, status, crashedOrErrored); - if (session != null) { - final SentryEnvelopeItem sessionItem = SentryEnvelopeItem.fromSession(serializer, session); - envelopeItems.add(sessionItem); - } + // update session and add it to envelope if necessary + final @Nullable Session session = updateSession(hub, options, status, crashedOrErrored); + if (session != null) { + final SentryEnvelopeItem sessionItem = SentryEnvelopeItem.fromSession(serializer, session); + envelopeItems.add(sessionItem); + } - final SentryEnvelope repackagedEnvelope = - new SentryEnvelope(envelope.getHeader(), envelopeItems); - return hub.captureEnvelope(repackagedEnvelope); + final SentryEnvelope repackagedEnvelope = + new SentryEnvelope(envelope.getHeader(), envelopeItems); + return hub.captureEnvelope(repackagedEnvelope); + } catch (Throwable t) { + options.getLogger().log(SentryLevel.ERROR, "Failed to capture envelope", t); + } + return null; } @Nullable 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 ba85423607..c27e199d6c 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 @@ -33,7 +33,6 @@ import java.util.concurrent.atomic.AtomicReference import kotlin.test.BeforeTest import kotlin.test.Test import kotlin.test.assertEquals -import kotlin.test.assertFails import kotlin.test.assertNotNull import kotlin.test.assertNull import kotlin.test.assertTrue @@ -204,9 +203,7 @@ class InternalSentrySdkTest { @Test fun `captureEnvelope fails if payload is invalid`() { - assertFails { - InternalSentrySdk.captureEnvelope(ByteArray(8)) - } + assertNull(InternalSentrySdk.captureEnvelope(ByteArray(8))) } @Test From dd366fd8f0434e7eaf1231cfb728206a66c65e1c Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Tue, 18 Jul 2023 10:39:20 +0200 Subject: [PATCH 3/5] Add Changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbbe2738bf..7b95305ca5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ - Fix ANRv2 thread dump parsing for native-only threads ([#2839](https://github.com/getsentry/sentry-java/pull/2839)) - Derive `TracingContext` values from event for ANRv2 events ([#2839](https://github.com/getsentry/sentry-java/pull/2839)) +### Features +- (Internal) Extend APIs for hybrid SDKs ([#2814](https://github.com/getsentry/sentry-java/pull/2814), [#2846](https://github.com/getsentry/sentry-java/pull/2846)) + ## 6.25.2 ### Fixes From c74e828f0c2e77ff563d1cb687a832132576b42f Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Tue, 18 Jul 2023 14:56:05 +0200 Subject: [PATCH 4/5] Fix docstring --- .../src/main/java/io/sentry/android/core/InternalSentrySdk.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 04d4f9fc7e..5302199670 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 @@ -54,7 +54,7 @@ public static Scope getCurrentScope() { * @param options Sentry Options * @param scope the scope * @return a map containing all relevant scope data (user, contexts, tags, extras, fingerprint, - * level, breadcrumbs) or null if the scope itself is null or serialization fails + * level, breadcrumbs) */ @NotNull public static Map serializeScope( From a93f2b7c9c407a4b2089a8d41554993518d1eb86 Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Tue, 18 Jul 2023 15:30:20 +0200 Subject: [PATCH 5/5] Fix changelog order --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b95305ca5..9ca736c066 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,14 @@ ## Unreleased +### Features +- (Internal) Extend APIs for hybrid SDKs ([#2814](https://github.com/getsentry/sentry-java/pull/2814), [#2846](https://github.com/getsentry/sentry-java/pull/2846)) + ### Fixes - Fix ANRv2 thread dump parsing for native-only threads ([#2839](https://github.com/getsentry/sentry-java/pull/2839)) - Derive `TracingContext` values from event for ANRv2 events ([#2839](https://github.com/getsentry/sentry-java/pull/2839)) -### Features -- (Internal) Extend APIs for hybrid SDKs ([#2814](https://github.com/getsentry/sentry-java/pull/2814), [#2846](https://github.com/getsentry/sentry-java/pull/2846)) - ## 6.25.2 ### Fixes