diff --git a/CHANGELOG.md b/CHANGELOG.md index b74bc0886e..994ee075f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 8.34.0 + +### Fixes + +- Fix crash when unregistering `SystemEventsBroadcastReceiver` with try-catch block. ([#5106](https://github.com/getsentry/sentry-java/pull/5106)) + ## 8.33.0 ### Features diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java index a5e56fcc3f..5c3e0575bb 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java @@ -203,13 +203,13 @@ private void scheduleUnregisterReceiver() { } try { - options.getExecutorService().submit(() -> unregisterReceiver()); + options.getExecutorService().submit(() -> unregisterReceiver(options)); } catch (RejectedExecutionException e) { - unregisterReceiver(); + unregisterReceiver(options); } } - private void unregisterReceiver() { + private void unregisterReceiver(final @NotNull SentryAndroidOptions options) { final @Nullable SystemEventsBroadcastReceiver receiverRef; try (final @NotNull ISentryLifecycleToken ignored = receiverLock.acquire()) { isStopped = true; @@ -218,7 +218,16 @@ private void unregisterReceiver() { } if (receiverRef != null) { - context.unregisterReceiver(receiverRef); + try { + context.unregisterReceiver(receiverRef); + } catch (IllegalArgumentException exception) { + options + .getLogger() + .log( + SentryLevel.ERROR, + exception, + "Failed to unregister SystemEventsBroadcastReceiver: the receiver is already unregistered or was never registered."); + } } } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegrationTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegrationTest.kt index fe5e6c775b..2505b6f7f7 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegrationTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegrationTest.kt @@ -52,6 +52,7 @@ class SystemEventsBreadcrumbsIntegrationTest { lateinit var shadowActivityManager: ShadowActivityManager fun getSut( + contextForSut: Context = context, enableSystemEventBreadcrumbs: Boolean = true, enableSystemEventBreadcrumbsExtras: Boolean = false, executorService: ISentryExecutorService = ImmediateExecutorService(), @@ -64,7 +65,7 @@ class SystemEventsBreadcrumbsIntegrationTest { this.executorService = executorService } return SystemEventsBreadcrumbsIntegration( - context, + contextForSut, SystemEventsBreadcrumbsIntegration.getDefaultActions().toTypedArray(), handler, ) @@ -313,6 +314,20 @@ class SystemEventsBreadcrumbsIntegrationTest { assertFalse(fixture.options.isEnableSystemEventBreadcrumbs) } + @Test + fun `Do not crash if receiver already unregistered`() { + val realContext = ApplicationProvider.getApplicationContext() + val sut = fixture.getSut(realContext) + + sut.register(fixture.scopes, fixture.options) + + realContext.unregisterReceiver(sut.receiver) + + val result = runCatching { sut.onBackground() } + + assertFalse(result.isFailure) + } + @Test fun `when str has full package, return last string after dot`() { val sut = fixture.getSut()