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 FlutterError.

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:

// 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 */});



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:

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);

}



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.

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