Flutter & Dart 中的异常处理

Flutter & Dart 中的异常处理

哪些场景下需要错误处理介入

同步代码

同步代码中,try-catch-finally是最常用的错误处理方式
rethrow可以将错误信息重新上抛

     try {
        print('Allocate something 3');
        throw 'Other error occurred';
      } on IntegerDivisionByZeroException {
        print('Cant divide to zero');
      } on FormatException catch (e) {
        print('Format exceptions: $e');
      } catch (e, s) {
        print('Unknown exceptions: $e, with stack: \n$s');
        rethrow;
      } finally {
        print('Clean-up something 3');
      }

异步代码

异步代码的错误处理也是用try-catch-finally,但要注意写法
下面是错误的例子

      try {
        Future.delayed(Duration(seconds: 1), () {
          final _ = 100 ~/ 0;
        });
        print('Everything is fine!');
      } on IntegerDivisionByZeroException {
        print('Cant divide to zero');
      } finally {
        print('Clean-up done');
      }

为了能捕获到Futrue的错误可以有以下处理方式:

  1. 加await
      try {
        await Future.delayed(Duration(seconds: 1), () {
          final _ = 100 ~/ 0;
        });
        print('Everything is fine!');
      } on IntegerDivisionByZeroException {
        print('Cant divide to zero');
      } finally {
        print('Clean-up done');
      }

2.catchError & whenComplete结构
catchError是捕获上方代码的异常,是catch的模拟,如果想模拟finally,则可以在catchError后加whenComplete,
另外可以使用test来模拟on Exeption,判断异常的类型

      await Future.delayed(Duration(seconds: 1), () {
        print('Its fie so far');
      }).then((value) {
        print('Then started');
        throw 'random exception';
      }).catchError((error) {
        print('Cant divide to zero');
      }, test: (e) => e is IntegerDivisionByZeroException).catchError((error) {
        print('All other exceptions: $error');
      }, test: (e) => true).whenComplete(() {
        print('Clean-up done');
      });

定时器

定时器使用ZonesrunZonedGuarded处理异常,Zones可以将timer,微任务,Future的回调包起来(黑盒的try-catch-finally),通过Zones对外的方法实现异常处理,注意,Zones里面捕获的异常是不会抛到上层,已经被Flutter框架捕获的异常,不会被runZoneGuarded捕获

      print('Current zone start in: ${Zone.current.toString()}');
      runZonedGuarded(() {
        print('Current zone inside runZoned: ${Zone.current.toString()} with name ${Zone.current['ZoneName']}');
        Timer.run(() {
          print('Timer runs.');
          throw Exception('[Timer] Bad thing happens!');
        });
        runZonedGuarded(
          () {
            print('Current zone (1) inside runZoned: ${Zone.current.toString()} with name ${Zone.current['ZoneName']}');
            Timer.run(() {
              print('Timer 1 runs. ');
              throw Exception('[Timer 1] Bad thing happens!');
            });Flutter & Dart 中的异常处理
          },
          (e, s) {
            print('Current zone (1) inside catch: ${Zone.current.toString()} with name ${Zone.current['ZoneName']}');
            print('Exception handled (1) $e, \n$s');
          },
          zoneValues: {'ZoneName': 'Second zone'},
        );
        print('Everything is fine!');
      }, (e, s) {
        print('Current zone inside catch: ${Zone.current.toString()} with name ${Zone.current['ZoneName']}');
        print('Exception handled $e, \n$s');
      }, zoneValues: {'ZoneName': 'First zone'});

流操作

流操作也是用Zone来捕获异常

Flutter App全局整体

使用FlutterError.onError回调方法,可以将上述捕获的异常记录下来,使用FlutterError.onError回调之前,要先WidgetsFlutterBinding.ensureInitialized()

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容