Repository navigation
fix: Create the JS client before the native SDK finishes starting - #1469
Open
lucas-zimerman wants to merge 5 commits into
Open
lucas-zimerman wants to merge 5 commits into
lucas-zimerman wants to merge 5 commits into
Conversation
Mirror @sentry/react-native: sdkInit calls the sibling init synchronously and starts the native SDK in the background. The native transport waits for native init and falls back to the fetch transport if it failed, so errors captured during app bootstrap are no longer dropped. Adds an onReady option and registers the native log listener before native init. Fixes #1463 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The core client's typed emit has no afterInit hook, so the call failed tsc -p tsconfig.build.json. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… is not started SentrySDK.configureScope only runs its callback when the SDK is started. The promise was resolved inside the callback, so it never settled when native init failed and the JS event pipeline stalled. Reject instead, like React Native which resolves outside the callback. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
lucas-zimerman
requested review from
alwx and
antonis
and removed request for
a team and
alwx
November 5, 2026 22:11
lucas-zimerman
commented
Nov 5, 2026
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 03ce6cc. Configure here.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…Init The JS client is now created before the native SDK finishes starting, so fetchNativeDeviceContexts/LogAttributes/Release/SdkInfo could reach native before SentrySDK.start ran on iOS. They now wait for NATIVE.nativeReady and reject without calling native when it failed. An onReady callback that throws no longer skips the afterInit event. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
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
sdkInitused to start the native SDK first and only call the sibling SDK'sinitonceNATIVE.initNativeSdk()resolved. That resolve comes back over the Capacitor bridge as a new task, so the framework bootstrap ran before any JS client existed and everything captured in that window was dropped.This follows the
@sentry/react-nativelayout (ReactNativeClient.init()→_initNativeSdk()):sdkInitnow callsoriginalInitsynchronously and starts the native SDK in the background.onReady({ didCallNativeInit })option and emitsafterIniton the client.NATIVE.nativeReadyholds the pending native init. The native transport waits for it before sending, so events captured during bootstrap are queued instead of dropped. If native failed or is disabled, the transport falls back to the fetch transport (it no longer re-runsoriginalInitwith restored options).initNativeSdk, so logs emitted during native init are not missed.fetchNativeDeviceContexts/fetchNativeLogAttributesresolved inside theSentrySDK.configureScopecallback, which never runs when the native SDK is not started, so the promise never settled and the JS event pipeline stalled. They now reject (Native SDK is not started), like React Native, which resolves outside the callback.💡 Motivation and Context
Fixes #1463
Errors during app bootstrap (including the framework failing to bootstrap and errors reaching Angular's
ErrorHandler) were silently dropped withNo client configured on scope. This was a regression compared to calling@sentry/angular'sinitdirectly.💚 How did you test it?
test/client.test.ts(client created before native resolves,onReady, listener order, failure path) and added readiness/fallback tests intest/transports/native.test.ts.tsc -p tsconfig.build.json, eslint and the full jest suite pass.example/ionic-angular-v8): acaptureMessageright afterSentry.initis dropped onmainand captured and delivered with this change.mainthe message is dropped. With this change it passesbeforeSendand the envelope is written and sent by the native SDK.beforeSend. After it, both do and the envelope is POSTed to ingest through the fetch transport.Not tested: a real native-side start failure (the failure was forced in JS), a real bootstrap crash on iOS, and the Vue example.
📝 Checklist
sendDefaultPIIis enabled🔮 Next steps
onReadyoption.nativeReady; they currently rely on the bridge handling calls in order, as React Native does.