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?
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:
Tools such as Sentry and Crashlytics have become a golden standard for native and cross platform apps, as they:
Let's see if we can reach these objectives with Flutter
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:
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>
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.
++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.
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.
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