From 90e6c7538d51013851e055be1a64e2a9f18b156b Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Fri, 4 Sep 2026 10:10:56 +0200 Subject: [PATCH 1/2] feat(android): Add anrProfilingSampleRate option Expose Android ANR profiling (stable since sentry-java 8.55.0) through a new `anrProfilingSampleRate` JS option. When set > 0.0, the SDK profiles the main thread while an ANR is happening and attaches the profile to the ANR event. The value flows through initNativeSdk's options passthrough and is applied via SentryAndroidOptions.setAnrProfilingSampleRate on the native side. Closes #6661 Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 4 +++ .../java/io/sentry/react/RNSentryStartTest.kt | 32 +++++++++++++++++++ .../java/io/sentry/react/RNSentryStart.java | 4 +++ packages/core/src/js/options.ts | 15 +++++++++ packages/core/test/wrapper.test.ts | 17 ++++++++++ 5 files changed, 72 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bc796cdc6..4187d16497 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ## Unreleased +### Features + +- Add `anrProfilingSampleRate` option to profile ANRs on Android ([#6672](https://github.com/getsentry/sentry-react-native/pull/6672)) + ### Dependencies - Bump Cocoa SDK from v9.26.1 to v9.27.0 ([#6670](https://github.com/getsentry/sentry-react-native/pull/6670)) diff --git a/packages/core/RNSentryAndroidTester/app/src/test/java/io/sentry/react/RNSentryStartTest.kt b/packages/core/RNSentryAndroidTester/app/src/test/java/io/sentry/react/RNSentryStartTest.kt index 2b42b0b90e..0c64b573ab 100644 --- a/packages/core/RNSentryAndroidTester/app/src/test/java/io/sentry/react/RNSentryStartTest.kt +++ b/packages/core/RNSentryAndroidTester/app/src/test/java/io/sentry/react/RNSentryStartTest.kt @@ -400,6 +400,38 @@ class RNSentryStartTest { assertEquals(5000L, options.ndkAppHangTimeoutIntervalMillis) } + @Test + fun `when anrProfilingSampleRate is set, the ANR profiling sample rate is applied`() { + val rnOptions = JavaOnlyMap.of("anrProfilingSampleRate", 0.5) + val options = SentryAndroidOptions() + + RNSentryStart.getSentryAndroidOptions(options, rnOptions, logger) + + assertEquals(0.5, options.anrProfilingSampleRate!!, 0.0) + assertTrue("ANR profiling should be enabled", options.isAnrProfilingEnabled) + } + + @Test + fun `when anrProfilingSampleRate is not set, it remains at default (disabled)`() { + val rnOptions = JavaOnlyMap() + val options = SentryAndroidOptions() + + RNSentryStart.getSentryAndroidOptions(options, rnOptions, logger) + + assertNull("ANR profiling sample rate should be null by default", options.anrProfilingSampleRate) + assertFalse("ANR profiling should be disabled by default", options.isAnrProfilingEnabled) + } + + @Test + fun `when anrProfilingSampleRate is not a number, it is ignored`() { + val rnOptions = JavaOnlyMap.of("anrProfilingSampleRate", "invalid") + val options = SentryAndroidOptions() + + RNSentryStart.getSentryAndroidOptions(options, rnOptions, logger) + + assertNull("ANR profiling sample rate should remain null", options.anrProfilingSampleRate) + } + @Test fun `network detail replay options are forwarded to the native replay options`() { val mobileReplayOptions = diff --git a/packages/core/android/src/main/java/io/sentry/react/RNSentryStart.java b/packages/core/android/src/main/java/io/sentry/react/RNSentryStart.java index 2ee396b239..5e7f750c15 100644 --- a/packages/core/android/src/main/java/io/sentry/react/RNSentryStart.java +++ b/packages/core/android/src/main/java/io/sentry/react/RNSentryStart.java @@ -202,6 +202,10 @@ static void getSentryAndroidOptions( if (rnOptions.hasKey("enableAnrFingerprinting")) { options.setEnableAnrFingerprinting(rnOptions.getBoolean("enableAnrFingerprinting")); } + if (rnOptions.hasKey("anrProfilingSampleRate") + && rnOptions.getType("anrProfilingSampleRate") == ReadableType.Number) { + options.setAnrProfilingSampleRate(rnOptions.getDouble("anrProfilingSampleRate")); + } if (rnOptions.hasKey("enableNdkAppHangTracking")) { options.setEnableNdkAppHangTracking(rnOptions.getBoolean("enableNdkAppHangTracking")); } diff --git a/packages/core/src/js/options.ts b/packages/core/src/js/options.ts index 3780539caf..6b59decd06 100644 --- a/packages/core/src/js/options.ts +++ b/packages/core/src/js/options.ts @@ -103,6 +103,21 @@ export interface BaseReactNativeOptions { */ enableAnrFingerprinting?: boolean; + /** + * Sample rate for profiling ANR (Application Not Responding) events. + * + * When set to a value greater than `0.0`, the SDK profiles the main thread while an ANR is + * happening and attaches the resulting profile to the ANR event. The value is the probability + * (`0.0`–`1.0`) that any given ANR is profiled. + * + * Requires ANR detection, which is enabled by default. This is independent of UI/transaction + * profiling configured via `profilesSampleRate` and `_experiments.profilingOptions`. + * + * @default undefined (ANR profiling disabled) + * @platform android + */ + anrProfilingSampleRate?: number; + /** * When enabled, all the threads are automatically attached to all logged events on Android * diff --git a/packages/core/test/wrapper.test.ts b/packages/core/test/wrapper.test.ts index dee934f4bd..c98a7527e4 100644 --- a/packages/core/test/wrapper.test.ts +++ b/packages/core/test/wrapper.test.ts @@ -177,6 +177,23 @@ describe('Tests Native Wrapper', () => { expect(debug.warn).toHaveBeenLastCalledWith('Note: Native Sentry SDK is disabled.'); }); + test('forwards anrProfilingSampleRate to the Native SDK', async () => { + await NATIVE.initNativeSdk({ + dsn: VALID_DSN, + enableNative: true, + autoInitializeNativeSdk: true, + anrProfilingSampleRate: 0.5, + devServerUrl: undefined, + defaultSidecarUrl: undefined, + mobileReplayOptions: undefined, + }); + + expect(RNSentry.initNativeSdk).toHaveBeenCalled(); + // @ts-expect-error mock value + const initParameter = RNSentry.initNativeSdk.mock.calls[0][0]; + expect(initParameter.anrProfilingSampleRate).toBe(0.5); + }); + test('filter beforeSend when initializing Native SDK', async () => { await NATIVE.initNativeSdk({ dsn: VALID_DSN, From 803f47f045197e81a7c10683ae041c04f57fadbd Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Fri, 4 Sep 2026 10:11:26 +0200 Subject: [PATCH 2/2] docs: Point changelog entry to PR #6673 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4187d16497..b5233eabb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ ### Features -- Add `anrProfilingSampleRate` option to profile ANRs on Android ([#6672](https://github.com/getsentry/sentry-react-native/pull/6672)) +- Add `anrProfilingSampleRate` option to profile ANRs on Android ([#6673](https://github.com/getsentry/sentry-react-native/pull/6673)) ### Dependencies