Skip to content

fix(core): [Unhandled Sessions 2] Make session cache writes session-id aware - #5920

Draft
buenaflor wants to merge 8 commits into
feat/unhandled-sessions-protocolfrom
feat/unhandled-sessions-cache
Draft

fix(core): [Unhandled Sessions 2] Make session cache writes session-id aware#5920
buenaflor wants to merge 8 commits into
feat/unhandled-sessions-protocolfrom
feat/unhandled-sessions-cache

Conversation

@buenaflor

@buenaflor buenaflor commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

PR Stack (Unhandled Sessions)


📜 Description

Makes the session file cache aware of which session it is acting on.

Two paths in EnvelopeCache.storeInternal previously ignored session identity:

  • SessionEnd deleted session.json unconditionally. A delayed End(A) arriving after a newer session B was persisted would delete B's file.
  • SessionStart always rotated session.json into previous_session.json and overwrote it. A delayed Start(A) arriving after A's own state had already advanced on disk would overwrite the newer snapshot.

Both now compare session ids (and, for SessionEnd, start times) before deleting or rotating. A stale end only preserves the current file when the current session is genuinely newer — a different id and a later start time. Everything else keeps the existing behaviour, including malformed envelopes and unreadable session files, which still delete as before.

Also adds EnvelopeCache.persistCurrentSession(Session) so a caller can flush the active session to disk outside the envelope-store path, and extracts readSessionFromEnvelope / readSessionFromDisk helpers.

💡 Motivation and Context

Needed by the next PR in the stack, which mutates the live session in place (flagging a non-terminating unhandled error) and persists it so the flag survives process death. Without session-id awareness, an unrelated in-flight SessionEnd or SessionStart could clobber that snapshot.

In practice this only changes observable behaviour for sessions carrying the flag from PR 1 — the preserve branch requires hasNonTerminatingUnhandledError() — so existing SDK flows are unaffected.

💚 How did you test it?

EnvelopeCacheTest grew coverage for delayed same-id SessionStart preserving a newer unhandled or higher-error snapshot, different-id starts still rotating, matching and mismatching SessionEnd, null session ids on both paths, malformed envelopes, and unreadable session files. Also verified the pre-existing AbnormalExit and NativeCrashExit recovery paths still win over the flag. 36 tests, all passing.

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

🔮 Next steps

The capture API that sets the flag, in the next PR in this stack.

#skip-changelog

⚠️ Merge this PR using a merge commit (not squash). Only the collection branch is squash-merged into main.

buenaflor and others added 3 commits August 10, 2026 11:25
SessionEnd previously deleted session.json unconditionally and
SessionStart always rotated it. A delayed end or start could therefore
drop a newer session snapshot. Both paths now compare session ids and
start times before deleting or rotating, and a new persistCurrentSession
lets callers flush the active session to disk.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 343.87 ms 408.20 ms 64.33 ms
Size 0 B 0 B 0 B

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
6b019b7 343.31 ms 417.23 ms 73.91 ms
d15471f 286.65 ms 314.68 ms 28.03 ms
d217708 409.83 ms 474.72 ms 64.89 ms
d500866 326.13 ms 378.70 ms 52.58 ms
fcec2f2 314.96 ms 373.66 ms 58.70 ms
d501a7e 314.55 ms 343.34 ms 28.79 ms
7414e9b 322.49 ms 378.88 ms 56.39 ms
fcec2f2 357.47 ms 447.32 ms 89.85 ms
a416a65 316.52 ms 359.67 ms 43.15 ms
983e0f0 350.64 ms 386.44 ms 35.79 ms

App size

Revision Plain With Sentry Diff
6b019b7 0 B 0 B 0 B
d15471f 1.58 MiB 2.13 MiB 559.54 KiB
d217708 1.58 MiB 2.10 MiB 532.97 KiB
d500866 0 B 0 B 0 B
fcec2f2 1.58 MiB 2.12 MiB 551.50 KiB
d501a7e 0 B 0 B 0 B
7414e9b 0 B 0 B 0 B
fcec2f2 1.58 MiB 2.12 MiB 551.50 KiB
a416a65 1.58 MiB 2.12 MiB 555.26 KiB
983e0f0 0 B 0 B 0 B

Previous results on branch: feat/unhandled-sessions-cache

Startup times

Revision Plain With Sentry Diff
843e4f9 324.76 ms 399.16 ms 74.40 ms

App size

Revision Plain With Sentry Diff
843e4f9 0 B 0 B 0 B

@sentry

sentry Bot commented Aug 10, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.52.0 (1) release

⚙️ sentry-android Build Distribution Settings

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant