feat(android): [Unhandled Sessions 3] Add internal non-terminating envelope capture - #5921
feat(android): [Unhandled Sessions 3] Add internal non-terminating envelope capture#5921buenaflor wants to merge 27 commits into
Conversation
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
|
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
📲 Install BuildsAndroid
|
Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| bb0ff41 | 344.70 ms | 413.82 ms | 69.12 ms |
| a979f23 | 333.24 ms | 391.02 ms | 57.78 ms |
| 05aa61d | 326.06 ms | 385.46 ms | 59.40 ms |
| fc5ccaf | 270.49 ms | 363.90 ms | 93.41 ms |
| 9ea89e8 | 308.06 ms | 358.16 ms | 50.10 ms |
| 6b019b7 | 403.90 ms | 546.09 ms | 142.19 ms |
| ad8da22 | 314.52 ms | 352.47 ms | 37.95 ms |
| 96eeafa | 361.43 ms | 455.07 ms | 93.63 ms |
| ed33deb | 343.30 ms | 362.41 ms | 19.10 ms |
| ee747ae | 554.98 ms | 611.50 ms | 56.52 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| bb0ff41 | 0 B | 0 B | 0 B |
| a979f23 | 0 B | 0 B | 0 B |
| 05aa61d | 0 B | 0 B | 0 B |
| fc5ccaf | 1.58 MiB | 2.13 MiB | 557.54 KiB |
| 9ea89e8 | 1.58 MiB | 2.28 MiB | 716.23 KiB |
| 6b019b7 | 0 B | 0 B | 0 B |
| ad8da22 | 1.58 MiB | 2.29 MiB | 719.83 KiB |
| 96eeafa | 1.58 MiB | 2.19 MiB | 620.21 KiB |
| ed33deb | 1.58 MiB | 2.13 MiB | 559.52 KiB |
| ee747ae | 1.58 MiB | 2.10 MiB | 530.95 KiB |
Previous results on branch: feat/unhandled-sessions-internal-api
Startup times
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| ed254d0 | 331.02 ms | 359.08 ms | 28.06 ms |
| 8014a1f | 304.46 ms | 376.38 ms | 71.92 ms |
| bc96797 | 321.86 ms | 377.38 ms | 55.52 ms |
| e854020 | 317.72 ms | 358.13 ms | 40.40 ms |
| 0ac26dc | 390.71 ms | 438.00 ms | 47.29 ms |
| 4f9af8d | 329.51 ms | 342.60 ms | 13.09 ms |
| f4f202f | 315.94 ms | 369.24 ms | 53.30 ms |
| 211ab30 | 314.79 ms | 389.47 ms | 74.68 ms |
| 0650636 | 387.86 ms | 457.88 ms | 70.02 ms |
| b696cfd | 320.00 ms | 358.66 ms | 38.66 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| ed254d0 | 0 B | 0 B | 0 B |
| 8014a1f | 0 B | 0 B | 0 B |
| bc96797 | 0 B | 0 B | 0 B |
| e854020 | 0 B | 0 B | 0 B |
| 0ac26dc | 0 B | 0 B | 0 B |
| 4f9af8d | 0 B | 0 B | 0 B |
| f4f202f | 0 B | 0 B | 0 B |
| 211ab30 | 0 B | 0 B | 0 B |
| 0650636 | 0 B | 0 B | 0 B |
| b696cfd | 0 B | 0 B | 0 B |
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
6 similar comments
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
56ab999 to
1906ec6
Compare
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
2 similar comments
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
06f5823 to
ae23921
Compare
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
ae23921 to
b2ff9d9
Compare
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
b2ff9d9 to
945602b
Compare
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
Co-authored-by: Cursor <cursoragent@cursor.com>
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
Co-authored-by: Cursor <cursoragent@cursor.com>
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
…nto feat/unhandled-sessions-internal-api
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
…ions-internal-api
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
…ions-internal-api
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
…ions-internal-api
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
captureEnvelopeNonTerminating called persistCurrentSession from inside the withSession callback, so synchronous session-file I/O ran while holding the scope sessionLock, on the platform thread for Flutter. Mutate under the lock and write the clone withSession returns, the way SentryClient.updateSessionData uses its snapshot. Co-authored-by: Cursor <cursoragent@cursor.com>
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit da288f8. Configure here.
…lock" This reverts commit da288f8.
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
…ions-internal-api
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
Three reviewers in a row read the persist as accidentally holding the scope lock, so say why it is deliberate. Also name abnormal alongside crashed as a terminal status that wins over the unhandled marker, following the Session javadoc. Co-authored-by: Cursor <cursoragent@cursor.com>
🚨 Detected changes in high risk code 🚨High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:
|
runningcode
left a comment
There was a problem hiding this comment.
This looks good aside from the exception handling!
| final @NotNull SentryOptions options, final @NotNull byte[] envelopeData) { | ||
| try (final InputStream envelopeInputStream = new ByteArrayInputStream(envelopeData)) { | ||
| return options.getEnvelopeReader().read(envelopeInputStream); | ||
| } catch (Exception e) { |
There was a problem hiding this comment.
We should only catch the exceptions expect to throw here. Looks like we expect IOException and IllegalArgumentException ?
| final SentryEnvelope repackagedEnvelope = | ||
| new SentryEnvelope(envelope.getHeader(), envelopeItems); | ||
| return scopes.captureEnvelope(repackagedEnvelope); | ||
| } catch (Throwable t) { |
There was a problem hiding this comment.
since we arent doing disk I/O inside the try/catch, why do we need this? which parts can throw Exceptions ?
| } | ||
|
|
||
| return scopes.captureEnvelope(envelope); | ||
| } catch (Exception e) { |
There was a problem hiding this comment.
We should try to capture the narrowest exception possible as written in the AGENTS.md file now. Might need to rebase to get this update.

PR Stack (Unhandled Sessions)
📜 Description
Adds
InternalSentrySdk.captureEnvelopeNonTerminating(byte[])for hybrid runtimes where an unhandled exception does not terminate the process.Unlike
captureEnvelope(byte[], boolean), it does not treathandled=falseas a crash. Instead it:Okwith the same session id on the scope,The session is finalized later by normal lifecycle (
endSession, background, or previous-session recovery) asunhandled, unless a terminal status takes over first, such ascrashedfor a native crash orabnormalfor an ANR.captureEnvelope(byte[], boolean)is unchanged.Also in this PR:
Scope.IWithSessionbecomes public soInternalSentrySdkcan mutate the session under the scope lock; it is the only consumer. It carries@ApiStatus.InternallikeIWithTransactionandIWithPropagationContext, so it is not supported API despite being public.eventStateOfreturningEnvelopeEventState, replacing two loops that computed the same booleans by different routes, plus a sharedreadEnvelope.Exceptionrather thanThrowable, soOutOfMemoryErrorand friends propagate instead of being swallowed. The existingcaptureEnvelopekeeps itscatch (Throwable).💡 Motivation and Context
Flutter forwards
handled=falseevents through the terminating hybrid capture path. That marks the sessioncrashedand may start a replacement session even though the Flutter process keeps running, incorrectly lowering crash-free session rates.💚 How did you test it?
New
InternalSentrySdkTestcoverage: the session stayingOkwith the same id and the flag persisted to disk;endSessionafterwards finalizing asunhandled; and a later hard crash finalizing the old session ascrashedand starting a freshOksession. ExistingcaptureEnvelopetests confirm that path is unchanged.📝 Checklist
sendDefaultPIIis enabled.🔮 Next steps
Update the Flutter Android bridge to use
captureEnvelopeNonTerminatingfor non-terminating unhandled events.