Flutter

Error Reporting in Flutter

Purpose

Flutter is a Dart-based cross-platform app development framework that has been gaining traction in the mobile development community and has been lauded for its animation capabilities. It went from being a playground framework to a seriously considered option for production apps. How does Flutter stand in terms of industrial standards for app development and exploitation?

TLDR

  • You can use Sentry to report errors from your Flutter projects
  • All error reporting services as of today need manual reporting in your Dart code
  • Flutter considers by default all errors as non-fatal
  • Native stack traces are not transmitted to the Dart error handlers


Crash reporting at a glance

When an app starts its life on the app stores, the most critical events that negatively affects the app's quality are its crashes. As you reach for a high quality standard, you need equally reliable ways to:

  • count crashes;
  • collect helpful details to diagnose them.

Tools such as Sentry and Crashlytics have become a golden standard for native and cross platform apps, as they:

  • provide detailed stack traces at the different app software layers (native, UI code?)
  • aggregate crashes data in easy-to-visualize ways

Let's see if we can reach these objectives with Flutter

General setup

Native errors get sent to Sentry as well, although with a less detailed stacktrace that a thrown ++code>FlutterError.++/code>

It is possible to get any error reporting service (e.g. Sentry, Crashlytics, Datadog?) running within your app, it can be used the following way:

  • Wrap your app inside a Zone, which is basically a try/catch block that catches uncaught asynchronous errors
  • In the runZoned call, pass your errorHandler which will report all app errors to your reporting service

The code should now look like this:

++pre>++code>// In your main.dart file
import 'dart:async';
/* Some imports and code */
void main() async {
  runZoned<Future<void>>(() async {
  runApp(MyApp());
}, onError: (error, stackTrace) {/* Handle your error here */});
++/code>++/pre>

Calling an error handling service

The Flutter team has provided an excellent guide on how to setup Sentry on your app here . You can easily setup crash reporting to Sentry with a Dart HTTP Sentry client that has been developed by the Flutter team themselves.

  • Get a DSN from sentry.io
  • Follow the guide mentioned above to create the zone and initialize / call the Sentry service. Your code should look like this:

++pre>++code>import 'dart:async'
import 'package:sentry/sentry.dart';
final SentryClient _sentry = new SentryClient(dsn:"EXAMPLE_DSN"); // Replace by your own DSN

Future<Null> _reportError(dynamic error, dynamic stackTrace) async {
 print('Caught error: $error');

 print('Reporting to Sentry.io...');

 final SentryResponse response = await _sentry.captureException(
   exception: error,
   stackTrace: stackTrace,
 );

 if (response.isSuccessful) {
   print('Success! Event ID: ${response.eventId}');
 } else {
   print('Failed to report to Sentry.io: ${response.error}');
 }
}
void main() async {
 runZoned(() async {
   runApp(MyApp());
}, onError: _reportError);
}
++/code>++/pre>

You should see something like this on your Sentry dashboard, in this example calling a non-existing native method. Notice that Sentry by default reports events as errors.

 

Sentry

 

Note: Crashlytics support status

There is an early stage Crashlytics pub package that you can setup following this guide. However, I was not able to see errors on my Crashlytics after 36h, so for now I rely on Sentry to monitor app errors and crashes. If someone managed to make it work, do not hesitate to reach out to me. I have put up an example repo here in case you want to check it out.

Note: Flutter errors are non-fatal

When running in dev mode or using a Zone, Flutter catches all kinds of errors and does not let the app crash. That's why handling errors Flutter-side will only log non-fatal errors. This is an ongoing issue in the official Flutter Crashlytics plugin, although it is possible to force a crash if you use the non-official Crashlytics plugin through the ++code>forceCrash++/code> option

Développeur mobile ?

Rejoins nos équipes