Flutter integration guide

Add BugSnag to your Flutter applications for Android and iOS.

This documentation is for version 2 of the BugSnag Flutter library. We recommend upgrading to the latest release using our Upgrade guide. Documentation for the current release can be found here.

Installation

Add bugsnag_flutter to your application with the flutter command line tool:

$ flutter pub add bugsnag_flutter

You can also manually add bugsnag_flutter to your pubspec.yaml:

  dependencies:
    bugsnag_flutter: ^2.0.0

Basic configuration

This section covers integration into Flutter-based apps. If you have integrated Flutter components into an existing Android or iOS app, read our Native-first setup guide.

In order to catch errors as early as possible and from as many sources as possible within your Flutter application, we recommend using bugsnag.start to wrap your application start:

import 'package:bugsnag_flutter/bugsnag_flutter.dart';

void main() => bugsnag.start(
  apiKey: 'your-api-key-here',
  runApp: () => runApp(const MyFlutterApp()),
);

You can find your API key in Project Settings from your BugSnag dashboard.

Project packages

To improve the visual display and grouping of errors in the dashboard, BugSnag needs to be aware of packages in your app that you consider part of your codebase (“in-project”).

Where possible, the Dart package from which you initialize BugSnag is used to determine which frames within a stacktrace are from in-project and which are out-of-project. If you are building with --split-debug-info, the package name is not available and so you need set it in the Project Packages configuration option when starting BugSnag.

You also need to set the names of any additional in-project Dart packages, and, if you have native modules:

For Android, code in the package specified in the app’s manifest file is considered in-project by default. If you have any additional in-project packages these must be added to projectPackages.

For iOS, in-project code will be detected automatically as long as dSYMs are uploaded. See our symbolication guide for more details on uploading these.

Network request breadcrumbs

If your app makes HTTP requests via the http package or dart:io library, you can use one of our packages to capture network requests as breadcrumbs in your error reports. For installation instructions, see our Customizing breadcrumbs guide.

Showing full stacktraces

If you are splitting debug information (--split-debug-info) when building your Flutter app, certain symbol and mapping files need to be uploaded for each of your builds in order to see the original method names, file paths and line numbers in the stacktraces that are reported on your dashboard. You also need to upload mapping files from your native iOS and Android app builds to ensure that crashes in native code are shown correctly. See the Showing full stacktraces guide for more details.

Reporting unhandled errors

After completing installation and basic configuration, unhandled Dart errors as well as native Android and iOS crashes will be automatically reported and appear on your BugSnag dashboard.

Unlike Dart errors and handled errors, crashes are sent to your BugSnag dashboard when the app next launches. On iOS, they will not be reported when the debugger is attached.

Reporting ANRs and fatal app hangs

Android

When the main thread of an Android app is blocked for too long, it appears unresponsive and the Android OS creates an Application Not Responding (ANR) error, presenting the user with a dialog option to force quit the app.

ANR detection is enabled by default as part of the basic configuration steps. If you wish to disable it, see the enabledErrorTypes configuration option.

ANRs are unlikely to occur in Dart code but can happen in native Android components.

ANRs are sent to your BugSnag dashboard when the app next launches. ANRs will not be reported when the debugger is attached.

iOS

When the main thread of an app is unresponsive for a period of time it will appear to have frozen and may be terminated by the system watchdog as described in Apple’s documentation.

Detection of these “fatal” app hangs is enabled by default as part of the basic configuration steps. If you wish to disable it, see the EnabledErrorTypes configuration option. By default fatal app hangs are reported when the app is terminated after the main thread has been unresponsive for 2000ms.

You can also report non-fatal app hangs (i.e. hangs that did not result in the app being killed) by configuring a minimum app hang threshold duration. This threshold applies to both fatal and non-fatal app hangs and is used by BugSnag to prepare an app hang event report when it is exceeded; if the app subsequently recovers from the hang, a non-fatal hang is reported otherwise a fatal hang will be reported if the app is terminated.

Fatal app hangs are sent to your BugSnag dashboard when the app next launches.

App hangs are unlikely to occur in Dart code but can happen in native iOS components.

See the Reporting app hangs guide for more information.

Reporting out-of-memory terminations

On iOS platforms, BugSnag automatically detects terminations of your app caused by the operating system due to high memory usage.

OOM detection is enabled by default as part of the basic configuration steps. If you wish to disable it, see the enabledErrorTypes configuration option.

OOMs are sent to your BugSnag dashboard when the app next launches. OOMs will not be reported when the debugger is attached.

Reporting thermal kills

On iOS platforms, BugSnag detects terminations of your app by the operating system due to the device overheating.

Thermal kill detection is enabled by default as part of the basic configuration steps. If you wish to disable it, see the enabledErrorTypes configuration option.

Thermal kill events are sent to your BugSnag dashboard when the app next launches. They will not be reported when the debugger is attached.

Reporting handled errors

If you would like to send non-fatal or handled errors to BugSnag, you can pass a name and description to BugSnag’s notify function from your code:

try {
  // Some potentially crashy code
} catch(e, stack) {
  bugsnag.notify(e, stack);
}

Adding diagnostics or adjusting severity

It can often be helpful to adjust the severity or attach custom diagnostics to handled errors. For more information, see Reporting handled errors.

Sending diagnostic data

Automatically captured diagnostics

BugSnag will automatically capture and attach the following diagnostic data to every error report:

  • Full stack traces for all threads.
  • App state including running time and time in foreground.
  • Build information including name, version/build and release stage.
  • Device specification including model, OS version, total memory and GPU information.
  • System state including orientation, free memory, available disk space and battery level.

For more information see Automatically captured data.

Attaching custom diagnostics

It can often be helpful to attach application-specific diagnostic data to error reports. This can be accomplished by setting a callback which will be invoked before any reports are sent to BugSnag:

bugsnag.addOnError((event) {
  event.addMetadata('account', { 'name': 'Acme Co.' });
  event.addMetadata('account', { 'paying_customer': true });

  // Return false if you'd like to stop this error being reported
  return true;
});

For more information, see Customizing error reports.

Identifying users

In order to correlate errors with customer reports, or to see a list of users who experienced each error, it is helpful to capture and display user information. BugSnag includes helpers for attaching an identifier, email address and name to reports that will be searchable in the dashboard.

By default we will generate a unique ID and send this ID along with every error report from an individual device. If you would like to override this identifier you can set the user ID property.

await bugsnag.setUser(id: '3', email: 'bugs.nag@bugsnag.com', name: 'Bugs Nag');

For more information, see Adding user data.

Logging breadcrumbs

In order to understand what happened in your application before each error, it can be helpful to leave short log statements that we call breadcrumbs. A configurable number of breadcrumbs are attached to each error report to help diagnose what events led to the error.

Automatically captured breadcrumbs

By default, BugSnag captures common events including:

  • Low memory warnings
  • Device rotation
  • Menu presentation
  • Screenshot capture (not the screenshot itself)
  • Undo and redo
  • Table view selection
  • Window visibility changes
  • Non-fatal errors
  • Log messages

Add our NavigatorObserver to your app’s navigation to collect breadcrumbs on navigation events in the lead-up to an error. See Customizing breadcrumbs for configuration instructions.

Network request breadcrumbs

If your app makes HTTP requests via the http package or dart:io library, you can use one of our packages to capture network requests as breadcrumbs in your error reports. For installation instructions, see our Customizing breadcrumbs guide.

Leaving custom breadcrumbs

You can use the leaveBreadcrumb method to log potentially useful events in your own applications:

await bugsnag.leaveBreadcrumb('User clicked a button');

BugSnag will keep track of the time and order of the breadcrumbs and show them on your dashboard.

Additional data can also be attached to breadcrumbs by providing the optional type and metadata parameters. For more information and examples for how custom breadcrumbs can be integrated, see Customizing breadcrumbs.

Session tracking

BugSnag tracks the number of “sessions” that happen within your application. This allows you to compare stability scores between releases and helps you to understand the quality of your releases.

Sessions are captured and reported by default. This behavior can be disabled using the autoTrackSessions configuration option.

BugSnag will automatically report a session each time the app is launched or enters the foreground after being in the background for at least 30 seconds.

For more information about controlling session tracking, see Capturing sessions.

Declaring feature flags and experiments

Monitor errors as you roll out features or run experiments and A/B tests by declaring your feature flag and experiment usage in the BugSnag client. You can use the Features dashboard to identify whether these features have introduced errors into your app.

await bugsnag.addFeatureFlags(const [
  BugsnagFeatureFlag('Checkout button color', 'Blue'),
  BugsnagFeatureFlag('New checkout flow'),
]);

For more information, see Feature flags & experiments.

Identifying crashes at launch

By default BugSnag will identify crashes that occur whilst your app is launching, allowing you to prioritize fixing high-impact launch crashes.

Additionally you can use BugSnag to detect recurrent launch crashes: allowing you to take evasive action in your app, such as resetting data or turning off application features.

Follow the Identifying crashes at launch guide to configure this functionality.

Next steps