From 3aff7f3486a2bd003e2264ec034adcdc1b9db0ee Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Tue, 22 Sep 2026 12:02:02 +0200 Subject: [PATCH 1/4] feat(core): Expose native network breadcrumb options Expose `enableNetworkBreadcrumbs` (iOS) and `enableNetworkEventBreadcrumbs` (Android) so apps can disable the native network breadcrumbs, which largely duplicate the JS `fetch`/`XHR` breadcrumbs. iOS is read by cocoa's dictionary parser; Android is mapped in RNSentryStart. Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 4 +++ .../java/io/sentry/react/RNSentryStart.java | 4 +++ packages/core/etc/sentry-react-native.api.md | 2 ++ packages/core/src/js/options.ts | 26 ++++++++++++++ packages/core/test/wrapper.test.ts | 34 +++++++++++++++++++ 5 files changed, 70 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8457032647..2325d5b097 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ## Unreleased +### Features + +- Expose `enableNetworkBreadcrumbs` (iOS) and `enableNetworkEventBreadcrumbs` (Android) to disable native network breadcrumbs ([#6747](https://github.com/getsentry/sentry-react-native/issues/6747)) + ### Fixes - Declare optional peer dependencies so imports resolve under strict and Plug'n'Play package managers ([#6729](https://github.com/getsentry/sentry-react-native/pull/6729)) 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 16f814011d..ccc9740c24 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 @@ -213,6 +213,10 @@ static void getSentryAndroidOptions( options.setNdkAppHangTimeoutIntervalMillis( rnOptions.getInt("ndkAppHangTimeoutIntervalMillis")); } + if (rnOptions.hasKey("enableNetworkEventBreadcrumbs")) { + options.setEnableNetworkEventBreadcrumbs( + rnOptions.getBoolean("enableNetworkEventBreadcrumbs")); + } if (rnOptions.hasKey("spotlight")) { if (rnOptions.getType("spotlight") == ReadableType.Boolean) { options.setEnableSpotlight(rnOptions.getBoolean("spotlight")); diff --git a/packages/core/etc/sentry-react-native.api.md b/packages/core/etc/sentry-react-native.api.md index e7713cec39..d19ba75f15 100644 --- a/packages/core/etc/sentry-react-native.api.md +++ b/packages/core/etc/sentry-react-native.api.md @@ -176,6 +176,8 @@ export interface BaseReactNativeOptions { enableNdk?: boolean; enableNdkAppHangTracking?: boolean; enableNdkScopeSync?: boolean; + enableNetworkBreadcrumbs?: boolean; + enableNetworkEventBreadcrumbs?: boolean; enableStallTracking?: boolean; enableTombstone?: boolean; // @internal diff --git a/packages/core/src/js/options.ts b/packages/core/src/js/options.ts index 6d340319fe..c52216ab83 100644 --- a/packages/core/src/js/options.ts +++ b/packages/core/src/js/options.ts @@ -234,6 +234,32 @@ export interface BaseReactNativeOptions { */ ndkAppHangTimeoutIntervalMillis?: number; + /** + * When enabled, the native iOS SDK records a breadcrumb for every network request. + * + * The JS SDK already records breadcrumbs for `fetch`/`XHR` requests, so the native + * network breadcrumbs are largely duplicates (deduplicated on a best-effort basis when + * merged into JS events). Disable this to stop the native layer from adding its own HTTP + * breadcrumbs and reduce breadcrumb noise. + * + * @default true + * @platform ios + */ + enableNetworkBreadcrumbs?: boolean; + + /** + * When enabled, the native Android SDK records a breadcrumb for every network request. + * + * The JS SDK already records breadcrumbs for `fetch`/`XHR` requests, so the native + * network breadcrumbs are largely duplicates (deduplicated on a best-effort basis when + * merged into JS events). Disable this to stop the native layer from adding its own HTTP + * breadcrumbs and reduce breadcrumb noise. + * + * @default true + * @platform android + */ + enableNetworkEventBreadcrumbs?: boolean; + /** * Use this feature to enable the Sentry MetricKit integration. * diff --git a/packages/core/test/wrapper.test.ts b/packages/core/test/wrapper.test.ts index bae5357274..6d10e3120b 100644 --- a/packages/core/test/wrapper.test.ts +++ b/packages/core/test/wrapper.test.ts @@ -200,6 +200,40 @@ describe('Tests Native Wrapper', () => { expect(initParameter.anrProfilingSampleRate).toBe(0.5); }); + test('forwards enableNetworkBreadcrumbs to the Native SDK', async () => { + await NATIVE.initNativeSdk({ + dsn: VALID_DSN, + enableNative: true, + autoInitializeNativeSdk: true, + enableNetworkBreadcrumbs: false, + 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.enableNetworkBreadcrumbs).toBe(false); + }); + + test('forwards enableNetworkEventBreadcrumbs to the Native SDK', async () => { + await NATIVE.initNativeSdk({ + dsn: VALID_DSN, + enableNative: true, + autoInitializeNativeSdk: true, + enableNetworkEventBreadcrumbs: false, + 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.enableNetworkEventBreadcrumbs).toBe(false); + }); + test('filter beforeSend when initializing Native SDK', async () => { await NATIVE.initNativeSdk({ dsn: VALID_DSN, From b6fb6c120c3f058a853386ee3172db7e39ad4da3 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Tue, 22 Sep 2026 12:02:50 +0200 Subject: [PATCH 2/4] docs: Point CHANGELOG entry at PR #6764 Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2325d5b097..d4475d2baf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ ### Features -- Expose `enableNetworkBreadcrumbs` (iOS) and `enableNetworkEventBreadcrumbs` (Android) to disable native network breadcrumbs ([#6747](https://github.com/getsentry/sentry-react-native/issues/6747)) +- Expose `enableNetworkBreadcrumbs` (iOS) and `enableNetworkEventBreadcrumbs` (Android) to disable native network breadcrumbs ([#6764](https://github.com/getsentry/sentry-react-native/pull/6764)) ### Fixes From a5380b06e7e0d6df9e831d705d6790d681994e81 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Tue, 22 Sep 2026 12:23:51 +0200 Subject: [PATCH 3/4] test(android): Add unit tests for enableNetworkEventBreadcrumbs mapping Cover getSentryAndroidOptions forwarding of enableNetworkEventBreadcrumbs onto SentryAndroidOptions for true/false, and that omitting the RN option preserves the native default (true). First unit coverage for this method. Co-Authored-By: Claude Opus 4.8 --- .../io/sentry/react/RNSentryStartTest.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 packages/core/android/src/test/java/io/sentry/react/RNSentryStartTest.java diff --git a/packages/core/android/src/test/java/io/sentry/react/RNSentryStartTest.java b/packages/core/android/src/test/java/io/sentry/react/RNSentryStartTest.java new file mode 100644 index 0000000000..1c4c63ae66 --- /dev/null +++ b/packages/core/android/src/test/java/io/sentry/react/RNSentryStartTest.java @@ -0,0 +1,50 @@ +package io.sentry.react; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.facebook.react.bridge.ReadableMap; +import io.sentry.ILogger; +import io.sentry.android.core.SentryAndroidOptions; +import org.junit.Test; + +/** + * Coverage for the native option mapping in {@link RNSentryStart#getSentryAndroidOptions} — that RN + * options forwarded from JS are applied onto {@link SentryAndroidOptions}. + */ +public class RNSentryStartTest { + + private static SentryAndroidOptions optionsFrom(ReadableMap rnOptions) { + final SentryAndroidOptions options = new SentryAndroidOptions(); + RNSentryStart.getSentryAndroidOptions(options, rnOptions, mock(ILogger.class)); + return options; + } + + @Test + public void enableNetworkEventBreadcrumbsForwardsTrue() { + final ReadableMap rnOptions = mock(ReadableMap.class); + when(rnOptions.hasKey("enableNetworkEventBreadcrumbs")).thenReturn(true); + when(rnOptions.getBoolean("enableNetworkEventBreadcrumbs")).thenReturn(true); + + assertTrue(optionsFrom(rnOptions).isEnableNetworkEventBreadcrumbs()); + } + + @Test + public void enableNetworkEventBreadcrumbsForwardsFalse() { + final ReadableMap rnOptions = mock(ReadableMap.class); + when(rnOptions.hasKey("enableNetworkEventBreadcrumbs")).thenReturn(true); + when(rnOptions.getBoolean("enableNetworkEventBreadcrumbs")).thenReturn(false); + + assertFalse(optionsFrom(rnOptions).isEnableNetworkEventBreadcrumbs()); + } + + @Test + public void enableNetworkEventBreadcrumbsPreservesNativeDefaultWhenUnset() { + final ReadableMap rnOptions = mock(ReadableMap.class); + + // Native default is true; omitting the RN option must not change it. + assertTrue(optionsFrom(rnOptions).isEnableNetworkEventBreadcrumbs()); + } +} From 2cade1b64f97e8696cefd15eabfac3a2db79b57f Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Tue, 22 Sep 2026 12:46:22 +0200 Subject: [PATCH 4/4] docs(core): Correct enableNetworkEventBreadcrumbs description The Android enableNetworkEventBreadcrumbs option gates connectivity/network-state breadcrumbs (network available/lost, capability changes, bandwidth/VPN), not per-HTTP-request breadcrumbs. Fix the JSDoc and split the CHANGELOG so it no longer describes it as duplicating JS HTTP breadcrumbs. iOS enableNetworkBreadcrumbs is unchanged and does cover HTTP requests. Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 3 ++- packages/core/src/js/options.ts | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4475d2baf..a74821de8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,8 @@ ### Features -- Expose `enableNetworkBreadcrumbs` (iOS) and `enableNetworkEventBreadcrumbs` (Android) to disable native network breadcrumbs ([#6764](https://github.com/getsentry/sentry-react-native/pull/6764)) +- Expose `enableNetworkBreadcrumbs` (iOS) to disable native HTTP request breadcrumbs ([#6764](https://github.com/getsentry/sentry-react-native/pull/6764)) +- Expose `enableNetworkEventBreadcrumbs` (Android) to disable native network connectivity breadcrumbs ([#6764](https://github.com/getsentry/sentry-react-native/pull/6764)) ### Fixes diff --git a/packages/core/src/js/options.ts b/packages/core/src/js/options.ts index c52216ab83..5b6a291d4f 100644 --- a/packages/core/src/js/options.ts +++ b/packages/core/src/js/options.ts @@ -248,12 +248,13 @@ export interface BaseReactNativeOptions { enableNetworkBreadcrumbs?: boolean; /** - * When enabled, the native Android SDK records a breadcrumb for every network request. + * When enabled, the native Android SDK records breadcrumbs for network connectivity + * changes (network available/lost, capability changes such as WiFi <-> cellular, and + * bandwidth/VPN state). * - * The JS SDK already records breadcrumbs for `fetch`/`XHR` requests, so the native - * network breadcrumbs are largely duplicates (deduplicated on a best-effort basis when - * merged into JS events). Disable this to stop the native layer from adding its own HTTP - * breadcrumbs and reduce breadcrumb noise. + * These track the device's network state, not individual HTTP requests, so they are + * distinct from the `fetch`/`XHR` breadcrumbs the JS SDK records. Disable this to stop + * the native layer from adding connectivity breadcrumbs and reduce breadcrumb noise. * * @default true * @platform android