可以分为三大类
局部捕获
//使用try-catch捕获同步异常
try {
throw StateError('This is a Dart exception');
}catch(e) {
print(e);
}
//使用catchError捕获异步异常
Future.delayed(Duration(seconds: 1))
.then((e) => throw StateError('This is a Dart exception in Future.'))
.catchError((e)=>print(e));
全局捕获:在dart代码中,zone表示一段代码执行的范围,概念类似iOS的沙盒,不同沙盒之间是相互隔离的。如果想要处理zone中代码执行的异常,可以通过其提供的onError回调来处理,如下:
//同步抛出异常
runZoned(() {
throw StateError('This is a Dart exception.');
}, onError: (dynamic e, StackTrace stack) {
print('Sync error caught by zone');
});
//异步抛出异常
runZoned(() {
Future.delayed(Duration(seconds: 1))
.then((e) => throw StateError('This is a Dart exception in Future.'));
}, onError: (dynamic e, StackTrace stack) {
print('Async error aught by zone');
});
Framework异常是指flutter框架引起的异常,通常是由于执行错误的应用代码造成Flutter框架底层异常判断引起的,当出现Framework异常时,系统会自动弹出一个的红色错误界面。之所以会弹出一个错误提示页面,是由于系统在调用build()方法构建页面时会进行try-catch处理,如果出现任何错误就会调用ErrorWidget页面展示异常信息,并且Flutter框架在很多关键位置都自动进行了异常捕获处理。
可以通过重写ErrorWidget.builder()方法给用户更友好的界面呈现,代码如下:
ErrorWidget.builder = (FlutterErrorDetails flutterErrorDetails){
//自定义错误提示页面
return Scaffold(
body: Center(
child: Text("Custom Error Widget"),
)
);
};
同时可以注册 FlutterError.onError
回调,用于收集 Flutter framework 外抛的异常。
综上所述,对于dart和framework两种异常,可以在main.dart统一处理,如下:
Future<Null> main() async {
FlutterError.onError = (FlutterErrorDetails details) async {
Zone.current.handleUncaughtError(details.exception, details.stack);
};
runZoned<Future<void>>(() async {
runApp(MyApp());
}, onError: (error, stackTrace) async {
await _reportError(error, stackTrace);
});
}
Future<Null> _reportError(dynamic error, dynamic stackTrace) async {
print('catch error='+error);
}
同时,对于开发环境和线上环境还需要区别对待。因为,对于开发环境遇到的错误,一般是可以立即定位并修复问题的,而对于线上问题才需要对日志进行上报。因此,对于错误日志上报,需要对开发环境和线上环境进行区分对待,如下所示:
Future<Null> main() async {
FlutterError.onError = (FlutterErrorDetails details) async {
if (isDebugMode) {
FlutterError.dumpErrorToConsole(details);
} else {
Zone.current.handleUncaughtError(details.exception, details.stack);
}
};
… //省略其他代码
}
bool get isDebugMode {
bool inDebugMode = false;
assert(inDebugMode = true);
return inDebugMode;
}
flutter engine 部分的异常,以Android 为例,主要为 libfutter.so发生的错误。
这部份可以直接交给native崩溃收集sdk来处理,比如 firebase crashlytics、 bugly、xCrash 等等