Flutter
athar_errors sends Dart errors, native crashes and (if you turn them on) breadcrumbs,
anonymized, to your app’s ingest host. It never interrupts the user.
Install
Not published yet
The package isn’t on pub.dev yet: it comes with your account, under the name below.
dependencies:
athar_errors: ^0.1.0
On Android, the app needs the INTERNET permission.
Start it
void main() => ErrorReporting.runGuarded(() async {
await ErrorReporting.init(const ErrorOptions(
dsn: 'https://ik_…@<your ingest host>/<app id>', // shown once, with the app's key
release: '4.2.0+420',
environment: 'production',
appVersion: '4.2.0',
inAppPackages: ['my_app'], // your own packages: their frames group the issue
));
runApp(const MyApp());
});
runGuardedreports errors that escape to the zone.inithooksFlutterError.onErrorandPlatformDispatcher.instance.onError. The handlers you had before still run right after it, so other tools and the debug console behave as before.
Native crashes
- Android: an uncaught JVM exception is written to a file, and then the app’s previous handler
runs, so the app dies exactly as before. Native (NDK) crashes and ANRs come from the system’s
exit records (Android 11+). They carry no stack, so each groups as one issue per kind
(
NativeCrash,ApplicationNotResponding), with the signal in its message when Android gives one. - iOS: an uncaught
NSExceptionis written to a file. Signals and watchdog kills come from MetricKit’s crash reports (iOS 14+), which iOS delivers on a later launch. - Either way, the crash is sent on the next launch as
fatal, with the version that crashed.
Everything else it can send
- A caught error:
ErrorReporting.captureError(e, stack). - Product events:
ErrorReporting.track('checkout.done', {'items': 3}). - Your user:
ErrorReporting.identify('your-user-id'). Use your own opaque id, never an email. It is kept across launches, andidentify(null)forgets it. - Breadcrumbs are off by default. With
breadcrumbs: true:- add
ErrorReporting.navigatorObservertonavigatorObservers, and route names are recorded as templates (/orders/:id, with no query string); ErrorReporting.addBreadcrumb('…')adds your own.
- add
The user’s profile (optional)
With profilesUrl and a publishable profilesKey (pk_…) in ErrorOptions,
identify('id', email: …, phone: '+…', attributes: {…}) also sets the user’s profile (the email
and phone are hashed by the service on arrival), track also records the event there, and
ErrorReporting.setConsent('push', true) records a channel choice. It is all queued (at most 200
items, 7 days) and follows the same opt-out. Without the two options nothing goes there.
What it collects
- Collected: the error type, its message and stack frames (function, library, line), and the app version, build, release and environment. Also the OS and its major version, phone or tablet, and the language. Frames never carry local variables or arguments.
- Scrubbed on the device first: emails, phone numbers and any run of 7+ digits, IP addresses,
tokens and keys, UUIDs, query strings, and home directories. Each becomes a placeholder (
<email>,<number>…). Add your own patterns withscrubPatterns; the built-in ones can’t be turned off. - Never collected: names, emails, device model or ids, advertising ids, location, IP addresses,
or anything on screen or typed. No UI of its own, ever. The one exception is opt-in: with
profilesUrlandprofilesKey, what you pass toidentifygoes to the user’s profile.
What it never does
- It never throws into your app. If the SDK itself fails, it turns itself off for the session.
- Offline: at most 50 items for up to 7 days, oldest dropped first, each at most 64 KB. They are sent when the app comes back to the foreground, with backoff while the service is unreachable. The same error more than 10 times a minute is counted once on the device.
Opt-out and consent
ErrorReporting.setEnabled(false)stops capture and deletes what is queued. It holds across launches.- Strict mode (
requireConsent: true) captures nothing untilErrorReporting.grantConsent();revokeConsent()deletes what’s queued.
Your privacy policy: a template
This app sends anonymous error reports to help us fix crashes. A report contains the error, the app and OS version, and the device type. It does not contain your name, email, account, location, IP address, or anything you typed. You can turn this off in Settings → [your switch]. Reports are kept for 30 days.
If you set profilesUrl and profilesKey, this template no longer covers you: say what you pass
to identify (an email, a phone, attributes), and what the user’s profile is used for.