runAppWithReporting static method
Bootstraps the app and reporting system.
Implementation
static Future<void> runAppWithReporting({
required Widget Function() app,
required ClientConfig config,
bool captureFrameworkErrors = true,
bool capturePlatformDispatcherErrors = true,
bool attachIsolateErrorListener = true,
bool useDefaultFlutterErrorPresentation = true,
}) async {
// Initialize the reporting client and pipeline.
await BugReportClient.instance.initialize(config);
// Flutter framework errors (build/layout/paint/etc.).
if (captureFrameworkErrors) {
final previous = FlutterError.onError;
FlutterError.onError = (FlutterErrorDetails details) {
if (useDefaultFlutterErrorPresentation) {
FlutterError.presentError(details);
} else {
// Preserve original handler if caller prefers custom presentation.
previous?.call(details);
}
final exception = _fromFlutterError(details);
// Fire-and-forget; no need to block UI thread.
unawaited(_report(exception));
};
}
// Platform dispatcher unhandled errors (e.g., errors bubbling past framework).
if (capturePlatformDispatcherErrors) {
final previous = ui.PlatformDispatcher.instance.onError;
ui.PlatformDispatcher.instance.onError =
(Object error, StackTrace stack) {
final exception = _normalize(error, stack);
final handledByPrevious = previous?.call(error, stack) ?? true;
unawaited(_report(exception));
// Returning true marks the error as handled.
return handledByPrevious && true;
};
}
// Other isolate errors.
if (attachIsolateErrorListener) {
_attachIsolateListener();
}
// Catch all remaining async uncaught errors in the root zone.
runZonedGuarded<void>(
() => runApp(app()),
(Object error, StackTrace stack) {
final exception = _normalize(error, stack);
unawaited(_report(exception));
},
);
}