Repository navigation
Conversation
Semver Impact of This PR⚪ None (no version bump detected) 📋 Changelog PreviewThis is how your changes will appear in the changelog. No changelog entries will be generated from this PR. 🤖 This preview updates automatically when you update the PR. |
🚨 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:
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## feat/3300-unhandled-session-status #4008 +/- ##
======================================================================
- Coverage 93.00% 88.58% -4.43%
======================================================================
Files 111 344 +233
Lines 4346 12295 +7949
======================================================================
+ Hits 4042 10891 +6849
- Misses 304 1404 +1100
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. |
There was a problem hiding this comment.
🔵 Needs a closer look
It changes the SDK event pipeline and introduces new native interop behavior (Android worker + Cocoa private API) where subtle platform/runtime differences warrant final human validation before approval.
Pull request overview
This PR adds an internal lifecycle hook for events dropped by event sampling and uses it in the Flutter SDK to notify native session tracking when an unhandled Dart/Flutter error is sampled out, keeping native session state accurate even when no envelope is forwarded.
Changes:
- Dispatch a new internal
OnEventSampledOutlifecycle event fromSentryClientwhen sampling drops an event (after processors andbeforeSend). - Add a Flutter
NativeSessionIntegrationthat listens for sampled-out unhandled errors and triggers a native session update via a newSentryNativeBindingmethod. - Implement the native binding plumbing across method channels (Darwin), Android worker/JNI path, and add targeted regression tests.
File summaries
| File | Description |
|---|---|
| packages/dart/lib/src/sentry_client.dart | Dispatches OnEventSampledOut when an event is dropped by sampling. |
| packages/dart/lib/src/sdk_lifecycle_hooks.dart | Adds internal lifecycle event OnEventSampledOut. |
| packages/dart/test/sentry_client_test.dart | Adds coverage for sampled-out lifecycle dispatch semantics. |
| packages/flutter/lib/src/sentry_flutter.dart | Registers the new native session integration on Android/iOS/macOS when native is enabled. |
| packages/flutter/lib/src/integrations/native_session_integration.dart | New integration that updates native sessions for sampled-out unhandled events. |
| packages/flutter/lib/src/native/sentry_native_binding.dart | Extends the binding contract with updateSessionForDroppedEventNonTerminating. |
| packages/flutter/lib/src/native/sentry_native_channel.dart | Implements the new binding method via method channels (non-Android). |
| packages/flutter/lib/src/native/java/sentry_native_java.dart | Implements the new binding method via the Android core worker. |
| packages/flutter/lib/src/native/java/android_core_worker.dart | Adds worker request + native call to update session for dropped non-terminating events. |
| packages/flutter/lib/src/native/c/sentry_native.dart | Adds unsupported stub for the new method on the C/FFI binding. |
| packages/flutter/lib/src/web/sentry_web.dart | Adds a “not supported” stub for web. |
| packages/flutter/darwin/sentry_flutter/Sources/sentry_flutter/SentryFlutterPlugin.swift | Adds method-channel handler calling Cocoa internal session update API. |
| packages/flutter/test/integrations/native_session_integration_test.dart | New unit tests for the integration behavior and lifecycle unregistration/error swallowing. |
| packages/flutter/test/sentry_flutter_test.dart | Updates platform integration expectations to include NativeSessionIntegration. |
| packages/flutter/test/sentry_native_channel_test.dart | Adds method-channel coverage for the new native binding call. |
| packages/flutter/test/native/android_core_worker_test_real.dart | Adds coverage ensuring the Android worker path awaits the session update request. |
| packages/flutter/test/native/sentry_native_java_test_real.dart | Updates fake worker to satisfy the new interface surface. |
| packages/flutter/test/sentry_native/sentry_native_test_ffi.dart | Adds unsupported-path test coverage for FFI binding. |
| packages/flutter/test/mocks.mocks.dart | Regenerates mocks to include the new binding method. |
Review details
- Files reviewed: 19/19 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
cfd42b9 to
c1fbd96
Compare
denrase
left a comment
There was a problem hiding this comment.
We should check if we need to do this if we drop for ANY reason, not just sampling.
We only wanna do this for sampling. if an event is dropped due to For details: https://develop.sentry.dev/sdk/foundations/client/#event-pipeline |
Dispatch sampled-out events after processing and update native session state for unhandled errors that do not produce an envelope. Fixes #3786 Co-Authored-By: Cursor <cursor@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Wrap the non-terminating session update handler signature to comply with the repository SwiftLint limit. Co-Authored-By: Cursor <cursor@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Clear the retained options reference after unregistering the sampled-out event callback during integration shutdown. Co-Authored-By: Cursor <cursor@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com>
f29ab52 to
ab35c53
Compare
📜 Description
Add an internal sampled-out event lifecycle hook and use it to keep native session state accurate when an unhandled Dart or Flutter event is dropped by sampling.
The native session integration:
beforeSendunhandled: truewhenmechanism.handled == falseStacked on #4007, which adopts the non-terminating envelope APIs. That PR is itself stacked on #4006.
Fixes #3786
💡 Motivation and Context
A sampled-out unhandled error has no envelope, so the native SDK cannot infer its session side effects from capture. Without a separate update, a gracefully ending session is incorrectly reported as exited instead of unhandled.
💚 How did you test it?
SentryClientsampling suite: 10 tests passedThe local macOS example build was blocked before compilation by Flutter's experimental Swift Package Manager override identity mismatch (
fluttervssentry_flutter); CI provides the platform build lane.📝 Checklist
sendDefaultPiiis enabledMade with Cursor