Open
Conversation
`RNSentryStart.createOptionsWithDictionary` (the live iOS init path since v8.0.0) did not read `_experiments.profilingOptions`, silently dropping `profileSessionSampleRate`, `lifecycle`, and `startOnAppStart`. The handling existed in `SentrySDKWrapper`, but that surface hasn't been called from `initNativeSdk` since #5582 — #5611 added the block to the wrong file. Port the handling to `RNSentryStart` and add XCTest coverage for the `startWithOptions` entry point that `initNativeSdk` uses, so this regression can't slip through again. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
Semver Impact of This PR⚪ None (no version bump detected) 📋 Changelog PreviewThis is how your changes will appear in the changelog.
🤖 This preview updates automatically when you update the PR. |
Contributor
Author
|
@sentry review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit dfbadc4. Configure here.
- Rewrite CHANGELOG entry to match the descriptive + PR-link format. - Strengthen the two positive profiling tests to invoke the installed callback on a fresh SentryProfileOptions probe and assert that sessionSampleRate, lifecycle, and profileAppStarts land correctly, so a future regression that installs an incomplete callback is caught. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7 tasks
This was referenced Apr 17, 2026
📲 Install BuildsAndroid
|
Contributor
iOS (new) Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 3817909+dirty | 1210.76 ms | 1215.64 ms | 4.89 ms |
| 3ce5254+dirty | 1217.70 ms | 1224.69 ms | 6.99 ms |
| 04207c4+dirty | 1228.55 ms | 1226.04 ms | -2.51 ms |
| 7ac3378+dirty | 1202.35 ms | 1198.31 ms | -4.04 ms |
| 5c1e987+dirty | 1208.43 ms | 1220.72 ms | 12.29 ms |
| 0d9949d+dirty | 1203.94 ms | 1202.27 ms | -1.67 ms |
| 4953e94+dirty | 1217.41 ms | 1223.53 ms | 6.12 ms |
| df5d108+dirty | 1207.34 ms | 1210.50 ms | 3.16 ms |
| a50b33d+dirty | 1207.11 ms | 1212.10 ms | 5.00 ms |
| 3d377b5+dirty | 1201.55 ms | 1201.80 ms | 0.25 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 3817909+dirty | 3.38 MiB | 4.73 MiB | 1.35 MiB |
| 3ce5254+dirty | 3.38 MiB | 4.76 MiB | 1.38 MiB |
| 04207c4+dirty | 3.38 MiB | 4.76 MiB | 1.38 MiB |
| 7ac3378+dirty | 3.38 MiB | 4.76 MiB | 1.38 MiB |
| 5c1e987+dirty | 3.38 MiB | 4.73 MiB | 1.35 MiB |
| 0d9949d+dirty | 3.38 MiB | 4.76 MiB | 1.38 MiB |
| 4953e94+dirty | 3.38 MiB | 4.73 MiB | 1.35 MiB |
| df5d108+dirty | 3.38 MiB | 4.73 MiB | 1.35 MiB |
| a50b33d+dirty | 3.38 MiB | 4.73 MiB | 1.35 MiB |
| 3d377b5+dirty | 3.38 MiB | 4.76 MiB | 1.38 MiB |
Contributor
iOS (legacy) Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 3817909+dirty | 1183.90 ms | 1187.50 ms | 3.60 ms |
| 3ce5254+dirty | 1219.93 ms | 1221.90 ms | 1.96 ms |
| 04207c4+dirty | 1191.27 ms | 1189.78 ms | -1.48 ms |
| 7ac3378+dirty | 1213.37 ms | 1218.15 ms | 4.78 ms |
| 5c1e987+dirty | 1204.30 ms | 1222.15 ms | 17.85 ms |
| 0d9949d+dirty | 1211.38 ms | 1219.67 ms | 8.29 ms |
| 4953e94+dirty | 1212.06 ms | 1214.83 ms | 2.77 ms |
| df5d108+dirty | 1225.90 ms | 1220.14 ms | -5.76 ms |
| a50b33d+dirty | 1197.74 ms | 1197.17 ms | -0.57 ms |
| 3d377b5+dirty | 1218.48 ms | 1219.51 ms | 1.03 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 3817909+dirty | 3.38 MiB | 4.73 MiB | 1.35 MiB |
| 3ce5254+dirty | 3.38 MiB | 4.76 MiB | 1.38 MiB |
| 04207c4+dirty | 3.38 MiB | 4.76 MiB | 1.38 MiB |
| 7ac3378+dirty | 3.38 MiB | 4.76 MiB | 1.38 MiB |
| 5c1e987+dirty | 3.38 MiB | 4.73 MiB | 1.35 MiB |
| 0d9949d+dirty | 3.38 MiB | 4.76 MiB | 1.38 MiB |
| 4953e94+dirty | 3.38 MiB | 4.73 MiB | 1.35 MiB |
| df5d108+dirty | 3.38 MiB | 4.73 MiB | 1.35 MiB |
| a50b33d+dirty | 3.38 MiB | 4.73 MiB | 1.35 MiB |
| 3d377b5+dirty | 3.38 MiB | 4.76 MiB | 1.38 MiB |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📢 Type of change
📜 Description
RNSentryStart.createOptionsWithDictionary— the live iOS init path reached fromSentry.init()viainitNativeSdk— does not read_experiments.profilingOptions. The JS wrapper packsprofilingOptionsinto_experiments.profilingOptions(wrapper.ts:306-312) and sends it across the bridge, but on iOS the dictionary is handed to Sentry Cocoa without theconfigureProfilingcallback being installed.profileSessionSampleRate,lifecycle, andstartOnAppStartare silently dropped.The handling exists in
SentrySDKWrapper.createOptionsWithDictionary(ios/SentrySDKWrapper.m:103-116), but that method hasn't been part ofinitNativeSdk's call path since #5582 moved init toRNSentryStart. #5611 then added the profiling block toSentrySDKWrapper(the already-bypassed file) a week later, so the feature has never reached Cocoa through the JS init path in any v8 release.This PR ports the
_experiments.profilingOptionshandling toRNSentryStart.createOptionsWithDictionaryand adds XCTest coverage — including one test againststartWithOptionsso the full entry point used byinitNativeSdkstays pinned. The positive tests invoke the installed callback on a probeSentryProfileOptionsand assertsessionSampleRate,lifecycle, andprofileAppStartsall land correctly, so a future incomplete callback regresses loudly.Scope is intentionally narrow. The same dead
SentrySDKWrapperoptions surface also contains_experiments.enableUnhandledCPPExceptionsV2handling that is unreached in the same way — that should be ported in a follow-up. (Top-levelenableLogsinSentrySDKWrapperis redundant, not broken: Cocoa'sSentryOptionsInternal.m:96already maps it from the raw dictionary.) Cleaning up the deadSentrySDKWrapper.createOptionsWithDictionary/setupWithDictionary(and their tests) is also a good follow-up — the reason this bug shipped is precisely that those dead-code tests kept passing.💡 Motivation and Context
iOS UI profiling is documented as available for React Native (https://docs.sentry.io/platforms/react-native/profiling/#ui-profiling-experimental), but no
profilingOptionsset through JSSentry.init({ _experiments: { profilingOptions: { ... } } })actually takes effect on iOS in any 8.x release. Users cannot opt into UI profiling via the documented path.💚 How did you test it?
#pragma mark - RNSentryStart Tests:testStartWithDictionaryInstallsConfigureProfilingFromExperimentsProfilingOptions— pins the fullstartWithOptionsentry point used byinitNativeSdk; invokes the installed callback on a probe and asserts all three fields land.testStartCreateOptionsWithDictionaryProfilingOptionsInstallsConfigureProfiling— unit test for the ported block; invokes the callback on a probe and asserts all three fields.testStartCreateOptionsWithDictionaryProfilingOptionsMissingDoesNotInstallConfigureProfiling+…EmptyExperimentsDoesNotInstall…— negative cases.#if SENTRY_TARGET_PROFILING_SUPPORTEDmatching the implementation inRNSentryExperimentalOptions.m.yarn build,yarn test(210 passing),yarn circularDepCheck,./scripts/clang-format.sh lint,yarn lint:android,yarn lint:kotlinall clean.yarn lint:oxlinthas 2 pre-existing errors insentryExpoNativeCheck.ts(unrelated; present on main). Full Cocoa XCTest run relies on CI's simulator.📝 Checklist
sendDefaultPIIis enabled🔮 Next steps
_experiments.enableUnhandledCPPExceptionsV2handling fromSentrySDKWrappertoRNSentryStart(same dead-code issue). fix(ios): honor _experiments.enableUnhandledCPPExceptionsV2 on v8 #6014