Skip to content

Commit

Permalink
docs(crashlytics): Use PlatformDispatcher.instance.onError for asyn…
Browse files Browse the repository at this point in the history
…c errors. Update Crashlytics example app to use "flutterfire-e2e-tests" project. (#9669)

Co-authored-by: Kevin Cheung <kevinthecheung@users.noreply.github.com>
  • Loading branch information
russellwheatley and kevinthecheung committed Oct 26, 2022
1 parent 02d7148 commit 8a0caa0
Show file tree
Hide file tree
Showing 12 changed files with 556 additions and 100 deletions.
50 changes: 29 additions & 21 deletions docs/crashlytics/_customize-crash-reports.md
Expand Up @@ -20,57 +20,62 @@ to disk to be sent along with the next fatal report or when the app restarts.

## Report uncaught exceptions {: #report-uncaught-exceptions}

You can automatically catch all errors that are thrown within the Flutter
You can automatically catch all "fatal" errors that are thrown within the Flutter
framework by overriding `FlutterError.onError` with
`FirebaseCrashlytics.instance.recordFlutterFatalError`:
`FirebaseCrashlytics.instance.recordFlutterFatalError`. Alternatively,
to also catch "non-fatal" exceptions, override `FlutterError.onError` with `FirebaseCrashlytics.instance.recordFlutterError`:

```dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// Pass all uncaught errors from the framework to Crashlytics.
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
bool weWantFatalErrorRecording = true;
FlutterError.onError = (errorDetails) {
if(weWantFatalErrorRecording){
FirebaseCrashlytics.instance.recordFlutterFatalError(errorDetails);
} else {
FirebaseCrashlytics.instance.recordFlutterError(errorDetails);
}
};
runApp(MyApp());
}
```

### Zoned errors {: #zoned-errors}

Not all errors are caught by Flutter. Sometimes, errors are instead caught by
`Zones`. A common case where relying on Flutter to catch errors would not be
enough is when an exception happens inside the `onPressed` handler of a button:
### Asynchronous errors {: #asynchronous-errors}

Asynchronous errors are not caught by the Flutter framework:

```dart
ElevatedButton(
onPressed: () {
onPressed: () async {
throw Error();
}
...
)
```

To catch such errors, you can use `runZonedGuarded`:
To catch such errors, you can use the `PlatformDispatcher.instance.onError` handler:

```dart
void main() async {
runZonedGuarded<Future<void>>(() async {
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// The following lines are the same as previously explained in "Handling uncaught errors"
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
FlutterError.onError = (errorDetails) {
FirebaseCrashlytics.instance.recordFlutterFatalError(errorDetails);
};
// Pass all uncaught asynchronous errors that aren't handled by the Flutter framework to Crashlytics
PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
runApp(MyApp());
}, (error, stack) => FirebaseCrashlytics.instance.recordError(error, stack, fatal: true));
}
```

Note: You must call `WidgetsFlutterBinding.ensureInitialized()` _inside_
`runZonedGuarded`. Error handling wouldn’t work if
`WidgetsFlutterBinding.ensureInitialized()` was called from the outside.

### Errors outside of Flutter {: #errors-outside-flutter}

To catch errors that happen outside of the Flutter context, install an error
Expand Down Expand Up @@ -108,6 +113,9 @@ await FirebaseCrashlytics.instance.recordError(
stackTrace,
reason: 'a non-fatal error'
);
// Or you can use:
await FirebaseCrashlytics.instance.recordFlutterError(errorDetails);
```

You may also wish to log further information about the error which is possible
Expand Down
26 changes: 14 additions & 12 deletions docs/crashlytics/_get-started.md
Expand Up @@ -66,29 +66,31 @@ void main() async {
await Firebase.initializeApp();
// Pass all uncaught errors from the framework to Crashlytics.
// Pass all uncaught "fatal" errors from the framework to Crashlytics
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
runApp(MyApp());
}
```

If you're using zones, instrumenting the zone’s error handler will catch errors
that aren't caught by the Flutter framework (for example, in a button’s
`onPressed` handler):
To catch asynchronous errors that aren't handled by the Flutter framework, use
`PlatformDispatcher.instance.onError`:


```dart
void main() async {
runZonedGuarded<Future<void>>(() async {
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FlutterError.onError =
FirebaseCrashlytics.instance.recordFlutterFatalError;
FlutterError.onError = (errorDetails) {
FirebaseCrashlytics.instance.recordFlutterFatalError(errorDetails);
};
// Pass all uncaught asynchronous errors that aren't handled by the Flutter framework to Crashlytics
PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
runApp(MyApp());
}, (error, stack) =>
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true));
}
```

Expand Down

0 comments on commit 8a0caa0

Please sign in to comment.