Issue
Our Flutter app shows a much lower crash-free rate in Sentry than in Google Play. Sentry defines a crash as an unhandled error or a hard crash, but in Flutter some unhandled errors do not actually crash the app. We want to stop these non-crashing unhandled errors from lowering the crash-free rate so our release health thresholds are accurate.
Applies To
All SaaS Customers and Self-Hosted Users
Release Health
Flutter SDK
Resolution
On Flutter, errors the SDK collects automatically are marked with level fatal by default, and fatal events count as crashes in the crash-free rate, even when the app keeps running. You have three ways to change this, from broadest to most targeted.
Option 1: Report auto-collected errors as error instead of fatal (recommended)
Set markAutomaticallyCollectedErrorsAsFatal to false during initialization. Automatically collected unhandled errors are then reported at level error, so they no longer affect the crash-free rate, while real crashes detected by the native layer stay fatal.
await SentryFlutter.init((options) {
options.dsn = 'YOUR_DSN';
options.markAutomaticallyCollectedErrorsAsFatal = false;
});
This option is documented in the Flutter SDK options reference.
Option 2: Mark exceptions as handled in beforeSend
Use beforeSend to set each exception's mechanism.handled to true before the event is sent. Handled events do not count against the crash-free rate.
await SentryFlutter.init((options) {
options.dsn = 'YOUR_DSN';
options.beforeSend = (event, hint) {
event.exceptions?.forEach((e) {
e.mechanism?.handled = true;
});
return event;
};
});
You can see how this beforeSend function works. On SDK versions before v9, use copyWith to update the mechanism instead of mutating it directly.
Option 3: Catch specific errors and capture them manually
Any error you catch in a try/catch block and pass to Sentry.captureException is treated as handled, so it does not lower the crash-free rate. Use this when you want to control specific code paths rather than change behavior globally.
try {
await doWork();
} catch (exception, stackTrace) {
await Sentry.captureException(exception, stackTrace: stackTrace);
}
Here is an example of capturing an exception.
Related articles
If you're still investigating how Sentry counts crashes for your release, these articles cover adjacent questions:
