getsentry / getsentry/sentry-react-native
Keep the native session's error count correct when a JS error is dropped by sampling
- Lingua principale
- TypeScript
- Stelle
- 1.8k
- Fork
- 366
- Merge medio
- 1g 5h
- PR unite (30g)
- 93
Descrizione
### 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 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](https://github.com/getsentry/sentry-dart/pull/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`.
### Native API (available now)
- **Android** — sentry-java 8.55.0 ([#5990](https://github.com/getsentry/sentry-java/pull/5990)), merged via #6658: `InternalSentrySdk.updateSessionForDroppedEventNonTerminating`.
- **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 #4008's internal lifecycle-hook design once it settles.
- **Bridge** — new bridge method `updateSessionForDroppedEventNonTerminating(unhandled: boolean)` (additive, backward-compatible; older cached native binaries simply no-op it).
- **Android / iOS** — forward to the respective native API; catch at the boundary, off-main where the native call persists.
- **Guard** — never call this for an event that also went through the #6659 capture path (double-count).
### Sequencing
- **Stacked after #6659.** Shares the non-terminating session plumbing and the no-double-count rule; #6659's capture path is the stable base.
- **Hold on the JS hook design** until Flutter #4008 (still open/unmerged) settles — it's the novel part most likely to be reshaped in review.
- **Same milestone as #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`/`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.
Guida per i contributori
Apri la guida per i contributori
Direzione di ricerca
Inizia dal percorso client degli eventi campionati e dal flusso bridge esistente in wrapper.ts:196-235 e RNSentryModuleImpl.java:500-511, quindi esamina il plumbing impilato di #6659 e RNSentry.podspec. Conferma le API native di forwarding per Android e iOS prima di definire il design dell’hook JS. Il lavoro è completato quando gli errori campionati scartati aggiornano la sessione nativa con il valore unhandled del meccanismo, mentre gli scarti di beforeSend, i tipi ignorati e gli eventi già catturati non vengono conteggiati due volte né inviano un envelope.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- android, ios, react-native, typescript
- Ambito
- mobile, observability
- Tipo di issue
- Funzionalità
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Stato di attività
- Attiva
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 45/100