You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When an error event is dropped by sampling on the JS side (sampleRate), the envelope is never forwarded to native, so the native session never records that an error occurred — a session that should be errored (or unhandled) can finalize as healthy/exited. Adopt updateSessionForDroppedEventNonTerminating to update the native session's error count in that path, without sending an envelope.
This is the sampling-path counterpart to #6659 (which handles unhandled errors that do produce an envelope). It is the RN equivalent of Flutter #4008.
Targeted at the next RN SDK major and stacked after #6659 — see Sequencing below.
The drift
RN sessions are owned by the native SDK; JS forwards envelopes. The only native session signal is via captureEnvelope (wrapper.ts:196-235 → RNSentryModuleImpl.java:500-511). So when JS drops an error by sampleRate before it reaches captureEnvelope, native never learns an error occurred, and the session's errors count / status drifts. Same motivation as Flutter #4008: without a separate update, a gracefully ending session is reported as exited instead of errored/unhandled.
Scope — sampling only, NOT beforeSend
Call this only for events dropped by sampling. The native API contract is explicit (sentry-cocoa SentryInternalEnvelopeApi):
"Do not call this for events dropped by beforeSend or ignored exception types, and do not call it in addition to captureNonTerminating for the same event."
So this path must fire for sampleRate drops only — not beforeSend returning null, not ignored/denied exception types. Flutter #4008 does the same: it "receives only final events accepted by processors and beforeSend." (This corrects the original issue text, which mentioned beforeSend.)
The API takes an unhandled: boolean — set it from the dropped event's mechanism.handled === false.
iOS — sentry-cocoa 9.27.0 (pinned in RNSentry.podspec): SentrySDK.internal.envelope.updateSessionForDroppedEventNonTerminating(unhandled:).
Design sketch
JS — a "sampled-out event" hook in the client path: when an error event is dropped specifically by sampleRate (not beforeSend/ignored), call a new NATIVE method with the unhandled flag. Mirror Flutter chore(deps): bump rexml from 3.2.6 to 3.3.3 in /samples/react-native #4008's internal lifecycle-hook design once it settles.
Not an API/ABI break (additive bridge method, no public JS API change). It is a Release Health behavior shift — errored/unhandled session rates become more accurate under error sampling — so it belongs in the next major with a CHANGELOG note.
Follow-up from the 8.55.0 bump (#6658). Pairs with #6659.
Summary
When an error event is dropped by sampling on the JS side (
sampleRate), the envelope is never forwarded to native, so the native session never records that an error occurred — a session that should beerrored(orunhandled) can finalize as healthy/exited. AdoptupdateSessionForDroppedEventNonTerminatingto update the native session's error count in that path, without sending an envelope.This is the sampling-path counterpart to #6659 (which handles unhandled errors that do produce an envelope). It is the RN equivalent of Flutter #4008.
Targeted at the next RN SDK major and stacked after #6659 — see Sequencing below.
The drift
RN sessions are owned by the native SDK; JS forwards envelopes. The only native session signal is via
captureEnvelope(wrapper.ts:196-235→RNSentryModuleImpl.java:500-511). So when JS drops an error bysampleRatebefore it reachescaptureEnvelope, native never learns an error occurred, and the session'serrorscount / status drifts. Same motivation as Flutter #4008: without a separate update, a gracefully ending session is reported asexitedinstead oferrored/unhandled.Scope — sampling only, NOT
beforeSendCall this only for events dropped by sampling. The native API contract is explicit (sentry-cocoa
SentryInternalEnvelopeApi):So this path must fire for
sampleRatedrops only — notbeforeSendreturningnull, not ignored/denied exception types. Flutter #4008 does the same: it "receives only final events accepted by processors andbeforeSend." (This corrects the original issue text, which mentionedbeforeSend.)The API takes an
unhandled: boolean— set it from the dropped event'smechanism.handled === false.Native API (available now)
InternalSentrySdk.updateSessionForDroppedEventNonTerminating.RNSentry.podspec):SentrySDK.internal.envelope.updateSessionForDroppedEventNonTerminating(unhandled:).Design sketch
sampleRate(notbeforeSend/ignored), call a newNATIVEmethod with theunhandledflag. Mirror Flutter chore(deps): bump rexml from 3.2.6 to 3.3.3 in /samples/react-native #4008's internal lifecycle-hook design once it settles.updateSessionForDroppedEventNonTerminating(unhandled: boolean)(additive, backward-compatible; older cached native binaries simply no-op it).unhandledsessions (notcrashed) #6659 capture path (double-count).Sequencing
unhandledsessions (notcrashed) #6659. Shares the non-terminating session plumbing and the no-double-count rule; Report unhandled JS errors that don't terminate the process asunhandledsessions (notcrashed) #6659's capture path is the stable base.unhandledsessions (notcrashed) #6659 (next major).Release classification
Not an API/ABI break (additive bridge method, no public JS API change). It is a Release Health behavior shift —
errored/unhandledsession rates become more accurate under error sampling — so it belongs in the next major with a CHANGELOG note.Follow-up from the 8.55.0 bump (#6658). Pairs with #6659.