Installation

Raygun4Flutter adds a Flutter plugin to your app that captures and handles errors, and reports the error information to your Raygun Crash Reporting dashboard.

The plugin internally uses Raygun's Android and iOS providers to report crashes and custom errors to Raygun.

The file lib/raygun4flutter.dart provides the main API entry point for Flutter users. In there, the plugin sets up a MethodChannel to pass through the API calls to native Kotlin and Swift code in android/src and ios/Classes respectively.

  • Android API 16+
  • iOS 10.0+

Raygun4Flutter currently uses the following versions of the native providers behind the scenes:

  • Android: Raygun4Android 4.0.1
  • iOS: 1.5.3

Flutter for Web and Desktop are currently not supported.

Run this command:

$ flutter pub add raygun4flutter

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):

dependencies:
    raygun4flutter: ^1.1.1
    Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Now in your Dart code, you can use:

import 'package:raygun4flutter/raygun4flutter.dart';

Initialisation and version tracking

Call Raygun.init() with an API key to initialise RaygunClient on application start, for example, from your initState method.

class _MyAppState extends State<MyApp> {

  @override
  void initState() {
    super.initState();
    Raygun.init(apiKey:'12345');
  }

}

The .init() method can also accept an optional version argument. If this is supplied, the version of your app will be tracked across Raygun crash reports:

Raygun.init(apiKey:'12345',version:'1.4.5');

As an additional convenience way to set the version, a method .setVersion() is available. Typical use cases would most likely fall back to setting the app version in the .init() method call when you setup the library.

To be able to capture errors inside Flutter, you need to add a custom FlutterError.onError handler to your main method. That redirects Flutter errors to Raygun.

Note: This only works when the app is running in "Release" mode.

FlutterError.onError = (details) {
    // Default error handling
    FlutterError.presentError(details);

    // Raygun error handling
    Raygun.sendException(
      error: details.exception,
      stackTrace: details.stack,
    );
};

You can also catch Dart errors outside of the code controlled by the Flutter framework by calling to runApp from a runZonedGuarded and redirecting captured errors to Raygun. For example: errors that happen in asynchronous code.

Note: This works both in "Release" and "Debug" modes.

runZonedGuarded<Future<void>>(() async {
  runApp(MyApp());
}, (Object error, StackTrace stackTrace) {
  Raygun.sendException(
    error: error, 
    stackTrace: stackTrace
    );
});

Sending errors manually

Call Raygun.sendException(error, tags, customData, stackTrace) to send errors to Raygun.

For example:

try {
  // code that crashes
} catch (error) {
  Raygun.sendException(error: error);
}

All arguments but error are optional. This method is mainly a convenience wrapper around the more customisable .sendCustom() method that obtains the class name and the message from the error object.

Sending custom errors manually

Call Raygun.sendCustom(className, message, tags, customData, stackTrace) to send custom errors to Raygun with your own customised className and message. As with .sendException(), tags, customData and stackTrace are optional.

For example:

Raygun.sendCustom(
  className: 'MyApp',
  reason: 'test error message',
  tags: ['API','Tag2'],
  customData: {
    'custom1': 'value',
    'custom2': 42,
  },
  stackTrace: StackTrace.current,
);

Raygun supports tracking the unique customers who encounter bugs in your apps.

By default a device-derived UUID is transmitted. You can also add the currently logged in customer's data like this using an object of type RaygunUserInfo:

Raygun.setUser(
  RaygunUserInfo(
    identifier: '1234',
    firstName: 'FIRST',
    fullName: 'LAST',
    email: 'test@example.com',
  ),
);

To clear the currently logged in customer, call setUser(null).

There is an additional convenience method that offers a shortcut to just track your customer by an identifier only. If you use an email address to identify the user, please consider using setUser instead of setUserId as it would allow you to set the email address into both the identifier and email fields of the crash data to be sent.

Raygun.setUserId('1234');

Call with null to clear the user identifier: setUserId(null)


Tags

Raygun.setTags() sets a list of global tags that will be logged with every exception. This will be merged with other tags passed into manually created crash reports via sendException() and sendCustom().

Raygun.setTags(['Tag1','Tag2']);

Custom data

Raygun.setCustomData() sets a global map of key-value pairs that, similar to tags, that will be logged with every exception. This will be merged with other custom data passed into manually created crash reports via sendException() and sendCustom().

Raygun.setCustomData({
  'custom1': 'value',
  'custom2': 42,
});

Breadcrumbs

Breadcrumbs can be sent to Raygun to provide additional information to look into and debug issues stemming from crash reports. Breadcrumbs can be created in two ways.

Simple string: Call Raygun.recordBreadcrumb(message), where message is just a string:

Raygun.recordBreadcrumb('test breadcrumb');

Using RaygunBreadcrumbMessage:

Create your own RaygunBreadcrumbMessage object and send more than just a message with Raygun.recordBreadcrumb(RaygunBreadcrumbMessage).

The structure of the type RaygunBreadcrumbMessage is as shown here:

RaygunBreadcrumbMessage({
  required this.message,
  this.category,
  this.level = RaygunBreadcrumbLevel.info,
  this.customData,
  this.className,
  this.methodName,
  this.lineNumber,
});

Custom endpoints

Raygun supports sending data from Crash Reporting to your own endpoints. If you want to set custom endpoints, could can do so by setting them after you've initialised Raygun:

Raygun.setCustomCrashReportingEndpoint(url)

Please note that setting a custom endpoint will stop Crash Report or Real User Monitoring data from being sent to the Raygun backend.


Platform-specific notes

In addition to this documentation, depending on your project's requirements we recommend to go through the platform-specific documentation for Raygun4Android and Raygun4Apple as well.

Android

In your app's AndroidManifest.xml (usually located in your Flutter project's /android/src/main directory), make sure you have granted Internet permissions. Beneath the <manifest> element add:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Inside the <application> element, add:

<service android:name="com.raygun.raygun4android.services.CrashReportingPostService"
          android:exported="false"
          android:permission="android.permission.BIND_JOB_SERVICE"
          android:process=":crashreportingpostservice"/>

Also please be aware that depending on the complexity of your Android project setup and if you use R8 or Proguard with additional Android code, you might need to add some custom rules for Proguard-support. This is outlined in the Raygun4Android documentation.