Please explain to me what is the difference between them. Can they be used together or only separately?
runZonedGuarded catches Asynchronous exceptions and FlutterError.onError catches Synchronous exceptions.
Flutter App to demonstrate both behaviors:
import 'dart:async';
import 'package:flutter/material.dart';
Future<void> main() async {
// Application asynchronous uncaught exception handler
runZonedGuarded<Future<void>>(
// body,
() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
},
// onError
(Object uncaughtException, StackTrace stackTrace) async {
print("runZonedGuarded caught an Asynchronous exception");
print("Uncaught Exception: $uncaughtException");
print("Stacktrace:\n$stackTrace");
},
);
// Application syncronous uncaught exception handler
FlutterError.onError = (FlutterErrorDetails errorDetails) {
print("FlutterError.onError caught a Synchronous exception");
print("Uncaught Exception Details:\n$errorDetails");
};
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'FlutterError.onError vs. runZonedGuarded Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const HomePage(title: 'FlutterError.onError vs. runZonedGuarded Demo'),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key, required this.title});
final String title;
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>{
int _counter = 0;
Future<void> asynchronousError() async {
setState(() { _counter++; });
throw UnimplementedError();
}
void synchronousError() {
setState(() { _counter++; });
throw UnimplementedError();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'Count is: '
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineLarge
),
ElevatedButton(
onPressed: asynchronousError,
child: const Text("Cause Asynchronous Exception"),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: synchronousError,
child: const Text("Cause Synchronous Exception"),
),
],
),
),
),
);
}
}
DEBUG CONSOLE output when 'Cause Asynchronous Exception' button is tapped:
I/flutter (27723): runZonedGuarded caught an Asynchronous exception
I/flutter (27723): Uncaught Exception: UnimplementedError
I/flutter (27723): Stacktrace:
I/flutter (27723): #0 _HomePageState.asynchronousError (package:zone_test/main.dart:59:3)
I/flutter (27723): #1 _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1204:21)
I/flutter (27723): #2 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:345:24)
I/flutter (27723): #3 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:758:11)
I/flutter (27723): #4 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:383:5)
I/flutter (27723): #5 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:314:7)
I/flutter (27723): #6 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:721:9)
I/flutter (27723): #7 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:97:12)
I/flutter (27723): #8 PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:142:9)
I/flutter (27723): #9 _LinkedHashMapMixin.forEach (dart:_compact_hash:764:13)
I/flutter (27723): #10 PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:
I/ViewRootImpl@29f1b88[MainActivity](27723): Relayout returned: old=(0,0,1080,2220) new=(0,0,1080,2220) req=(1080,2220)0 dur=6 res=0x1 s={true 522720604160} ch=false
DEBUG CONSOLE output when 'Cause Synchronous Exception' button is tapped:
I/ViewRootImpl@29f1b88[MainActivity](27723): Relayout returned: old=(0,0,1080,2220) new=(0,0,1080,2220) req=(1080,2220)0 dur=5 res=0x1 s={true 522720604160} ch=false
I/flutter (27723): FlutterError.onError caught a Synchronous exception
I/flutter (27723): Uncaught Exception Details:
I/flutter (27723): ══╡ EXCEPTION CAUGHT BY GESTURE ╞════════════════════════════════
I/flutter (27723): The following UnimplementedError was thrown while handling a
I/flutter (27723): gesture:
I/flutter (27723): UnimplementedError
I/flutter (27723):
I/flutter (27723): When the exception was thrown, this was the stack:
I/flutter (27723): #0 _HomePageState.synchronousError (package:zone_test/main.dart:65:3)
I/flutter (27723): #1 _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1204:21)
I/flutter (27723): #2 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:345:24)
I/flutter (27723): #3 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:758:11)
I/flutter (27723): #4 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:383:5)
I/flutter (27723): #5 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:314:7)
I/flutter (27723): #6 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:721:9)
I/flutter (27723): #7 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router