diff --git a/CHANGELOG.md b/CHANGELOG.md index 81aa2effb2..532bdd29d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ ### Fixes +- Ignore JavascriptException to filter out obfuscated duplicate JS Errors on Android ([#4232](https://github.com/getsentry/sentry-react-native/pull/4232)) - Skips ignoring require cycle logs for RN 0.70 or newer ([#4214](https://github.com/getsentry/sentry-react-native/pull/4214)) - Enhanced accuracy of time-to-display spans. ([#4189](https://github.com/getsentry/sentry-react-native/pull/4189)) diff --git a/packages/core/RNSentryAndroidTester/app/src/test/java/io/sentry/react/RNSentryModuleImplTest.kt b/packages/core/RNSentryAndroidTester/app/src/test/java/io/sentry/react/RNSentryModuleImplTest.kt index f699f0d530..448715d43d 100644 --- a/packages/core/RNSentryAndroidTester/app/src/test/java/io/sentry/react/RNSentryModuleImplTest.kt +++ b/packages/core/RNSentryAndroidTester/app/src/test/java/io/sentry/react/RNSentryModuleImplTest.kt @@ -7,12 +7,14 @@ import com.facebook.react.bridge.JavaOnlyMap import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.WritableMap +import com.facebook.react.common.JavascriptException import io.sentry.ILogger import io.sentry.SentryLevel import io.sentry.android.core.SentryAndroidOptions import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -125,4 +127,11 @@ class RNSentryModuleImplTest { module.getSentryAndroidOptions(actualOptions, options, logger) assertFalse(actualOptions.isEnableSpotlight) } + + @Test + fun `the JavascriptException is added to the ignoredExceptionsForType list on initialisation`() { + val actualOptions = SentryAndroidOptions() + module.getSentryAndroidOptions(actualOptions, JavaOnlyMap.of(), logger) + assertTrue(actualOptions.ignoredExceptionsForType.contains(JavascriptException::class.java)) + } } diff --git a/packages/core/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java b/packages/core/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java index e291b78b2c..8191108ad2 100644 --- a/packages/core/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +++ b/packages/core/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java @@ -26,6 +26,7 @@ import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableNativeArray; import com.facebook.react.bridge.WritableNativeMap; +import com.facebook.react.common.JavascriptException; import com.facebook.react.modules.core.DeviceEventManagerModule; import io.sentry.HubAdapter; import io.sentry.ILogger; @@ -58,7 +59,6 @@ import io.sentry.android.core.internal.util.SentryFrameMetricsCollector; import io.sentry.android.core.performance.AppStartMetrics; import io.sentry.protocol.SdkVersion; -import io.sentry.protocol.SentryException; import io.sentry.protocol.SentryId; import io.sentry.protocol.SentryPackage; import io.sentry.protocol.User; @@ -274,20 +274,13 @@ protected void getSentryAndroidOptions( options.getExperimental().setSessionReplay(getReplayOptions(rnOptions)); options.getReplayController().setBreadcrumbConverter(new RNSentryReplayBreadcrumbConverter()); } + + // React native internally throws a JavascriptException. + // we want to ignore it on the native side to avoid sending it twice. + options.addIgnoredExceptionForType(JavascriptException.class); + options.setBeforeSend( (event, hint) -> { - // React native internally throws a JavascriptException - // Since we catch it before that, we don't want to send this one - // because we would send it twice - try { - SentryException ex = event.getExceptions().get(0); - if (null != ex && ex.getType().contains("JavascriptException")) { - return null; - } - } catch (Throwable ignored) { // NOPMD - We don't want to crash in any case - // We do nothing - } - setEventOriginTag(event); addPackages(event, options.getSdkVersion());