Flutter Dart回顾 —— 异常捕获、抛出

   2023-02-08 学习力0
核心提示:  一、Dart 异常捕获、抛出  在Dart中,异常分两类:同步异常和异步异常1、同步异常:Dart中同步异常可以通过try/on/catch/finally来捕获代码块异常,可以通过throw 关键字用来明确地抛出异常。如下案例:List testList = List();try {var s = testList[

  一、Dart 异常捕获、抛出

  在Dart中,异常分两类:同步异常和异步异常

1、同步异常:

Dart中同步异常可以通过try/on/catch/finally来捕获代码块异常,可以通过throw 关键字用来明确地抛出异常。如下案例:

List testList = List();

try {

  var s = testList[3];

  //代码逻辑

} on IntegerDivisionByZeroException {

  //使用on关键字,捕获特定类型的异常

} on NoSuchMethodError catch (e) {

  //使用on关键字,捕获特定类型的异常

  //代码段可以有多个 on / catch 块来处理多个异常

} catch (error, stacktrace) {

  // 没有指定类型,处理所有错误

  //catch 最多提供两个可选参数

  //第一个参数 error 类型为 Object,也就是异常是可以抛出任意对象。

  //第二个参数 stacktrace,表示异常堆栈。

  print('Something really unknown error: $error');

  print('Something really unknown stacktrace: $stacktrace');

  throw '抛出异常关键';

  //throw 之后的代码将不会执行

  //throw new FormatException();

} finally {

  // 在throw之前先执行finally代码块
  print("this is finally");

}

输出结果:

Flutter Dart回顾 —— 异常捕获、抛出

 

 

 

Dart中的每个异常类型都是内置类 Exception 的子类型。Dart可以通过扩展现有异常来创建自定义异常。定义自定义异常的语法如下所示

语法:定义异常

class Custom_exception_Name implements Exception {

   // can contain constructors, variables and methods

}
eg:

class AmtException implements Exception {

   String errMsg() => 'Amount should be greater than zero';

}  

throw new AmtException();

2、异步异常

try-catch 代码块不能捕获到异步异常,使用 await 关键字声明的同步调用,属于同步异常范围,可以通过 try-catch 捕获。

使用 catchError 捕获异步异常,第一个参数为 Function error 类型,第二个参数为 {bool test(Object error)},是一个判断表达式,当此表达式返回值为 true 时,表示需要执行 catch 逻辑,如果返回 false,则不执行 catch 逻辑,即会成为未捕获的异常,默认不传时 认为是true。

这里的作用是可以精细化的处理异常,可以理解为同步异常中强化版的 on 关键字,

入参至多两个 分别为error 和 stack,均可选。

Future(() {
}).then((value){ }).catchError((error, stack) { }); Future.delayed(Duration(seconds:
1)).then((e) => Future.error("xxx"));

 

  二、Flutter异常捕获、抛出

为了捕获并上报异常,可以把应用运行在一个自定义的 Zone 里面。 Zones 为代码建立执行上下文环境。在这个上下文环境中,所有发生的异常在抛出 onError 时都能够很容易地被捕获到。

Dart中有一个runZoned(...) 方法,可以给执行对象指定一个Zone。Zone表示一个代码执行的环境范围,为了方便理解,读者可以将Zone类比为一个代码执行沙箱,不同沙箱的之间是隔离的,沙箱可以捕获、拦截或修改一些代码行为,如Zone中可以捕获日志输出、Timer创建、微任务调度的行为,同时Zone也可以捕获所有未处理的异常。下面我们看看runZoned(...)方法定义:

R runZoned<R>(R body(), {

    Map zoneValues, 

    ZoneSpecification zoneSpecification,

    Function onError,

})

 

参数含义可参考《Flutter实战》https://book.flutterchina.club/chapter2/thread_model_and_error_report.html

在下面的例子中,将会把应用运行在一个新的 Zone 里面并捕获所有错误,在 1.17 之前的 Flutter 版本里,你可以通过 onError() 回调捕获所有的异常。

runZoned<Future<void>>(() async {

  runApp(MyApp());

}, onError: (error, stackTrace) {

  // Whenever an error occurs, call the `_reportError` function. This sends

  // Dart errors to the dev console or Sentry depending on the environment.

  _reportError(error, stackTrace);

});

 

在包含了 Dart 2.8 的 Flutter 1.17 中,使用 runZonedGuarded:

runZonedGuarded<Future<void>>(() async {

  runApp(MyApp());

}, (Object error, StackTrace stackTrace) {

  // Whenever an error occurs, call the `_reportError` function. This sends

  // Dart errors to the dev console or Sentry depending on the environment.

  _reportError(error, stackTrace);

});

 

 

除了 Dart 异常,Flutter 也能抛出其他的异常,比如调用原生代码发生的平台异常。这种类型的异常也同样是需要上报的。

为了捕获 Flutter 异常,需要重写 FlutterError.onError 属性。在开发环境下,可以将异常格式化输出到控制台。在生产环境下,可以把异常传递给上个步骤中的 onError 回调。

大致步骤如下:

Future<Null> main() async {

  //重写FlutterError.onError

  FlutterError.onError = (FlutterErrorDetails details) {

    if (isInDebugMode) {

      // In development mode, simply print to console.

      FlutterError.dumpErrorToConsole(details);

    } else {

      // In production mode, report to the application zone to report to

      // Sentry.

      Zone.current.handleUncaughtError(details.exception, details.stack);

    }

  };

  //使用runZonedGuarded捕获日志输出、Timer创建、微任务调度的行为、所有未处理的异常

  runZonedGuarded<Future<Null>>(

    () async {

      runApp(MyApp());

    },

    (error, stackTrace) async {

      await _reportErrorAndLog(error, stackTrace);

    },

    zoneSpecification: ZoneSpecification(

      print: (Zone self, ZoneDelegate parent, Zone zone, String line) async {

        await collectLog(line); // 收集日志

      },

    ),

  );

}

Future<Null> collectLog(String line) async {
  //收集日志
}

//上报错误和日志逻辑

Future<Null> _reportErrorAndLog(dynamic error, dynamic stackTrace) async {

  print('Caught error: $error');

  if (isInDebugMode) {

    print(stackTrace);

    print('In dev mode. Not sending report to Sentry.io.');

    return;
  }

  //TODO: response 为上传请求结果

  if (response.isSuccessful) {
    print('Success!');
  } else {
    print('Failed to report to Sentry.io: ${response}');
  }
}
//判断debug及release环境

bool get isInDebugMode {

  bool inDebugMode = false;

  assert(inDebugMode = true);

  return inDebugMode;
}

 

 

参考:

https://book.flutterchina.club/chapter2/thread_model_and_error_report.html

https://flutter.cn/docs/cookbook/maintenance/error-reporting

https://juejin.cn/post/6906274131394691085 

 

 

 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • Dart空安全的底层原理与适配
    Dart空安全的底层原理与适配
    一、在空安全推出之前,静态类型系统允许所有类型的表达式中的每一处都可以有 null。从类型理论的角度来说,Null 类型被看作是所有类型的子类;   类型会定义一些操作对象,包括 getters、setters、方法和操作符,在表达式中使用。如果是 List 类型,您可
    03-08
  • Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
    Flutter开发指南之理论篇:Dart语法05(单线程
    此文转载自:https://blog.csdn.net/AndrExpert/article/details/110823218Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate) Flutter开发指南之理论篇:Flutter基础01(架构,设计思想) Dart是一门面向对象语言,它针对web 和移
    03-08
  • Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
    Flutter开发指南之理论篇:Dart语法05(单线程
    此文转载自:https://blog.csdn.net/AndrExpert/article/details/110823218Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate) Flutter开发指南之理论篇:Flutter基础01(架构,设计思想) Dart是一门面向对象语言,它针对web 和移
    03-08
  • Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
    Flutter开发指南之理论篇:Dart语法05(单线程
    此文转载自:https://blog.csdn.net/AndrExpert/article/details/110823218Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate) Flutter开发指南之理论篇:Flutter基础01(架构,设计思想) Dart是一门面向对象语言,它针对web 和移
    03-08
  • oogle的“ JavaScript杀手” Dart 与JavaScript的比较
    oogle的“ JavaScript杀手” Dart 与JavaScript
    JavaScript通常被称为浏览器脚本语言,但它也已扩展到许多服务器端和移动应用程序开发环境。JS已经存在了将近20年,可以肯定地说它确实是一种成熟且稳定的编程语言。在Facebook发布React和React Native框架之后,JS变得越来越流行。JavaScript具有自己的软件
    03-08
  • Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
    Flutter开发指南之理论篇:Dart语法05(单线程
    此文转载自:https://blog.csdn.net/AndrExpert/article/details/110823218Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate) Flutter开发指南之理论篇:Flutter基础01(架构,设计思想) Dart是一门面向对象语言,它针对web 和移
    03-08
  • Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
    Flutter开发指南之理论篇:Dart语法05(单线程
    此文转载自:https://blog.csdn.net/AndrExpert/article/details/110823218Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate) Flutter开发指南之理论篇:Flutter基础01(架构,设计思想) Dart是一门面向对象语言,它针对web 和移
    03-08
  • flutter 填坑之旅(dart学习笔记篇)
    flutter 填坑之旅(dart学习笔记篇)
    俗话说 ‘工欲善其事必先利其器’ 想要撸flutter app 而不懂 dart 那就像一个不会英语的人在和英国人交流,懵!安装 dart 就不用说了,比较简单dart 官网 https://dart.dev/安装完成后就开启学习dart 旅程吧…一、 首先得找个ide (总不能使用记事本撸吧),所
    03-08
  • dart 命令行
       dart build 
    02-09
  • dart系列之:dart语言中的异常 dart新手的错误
    目录简介Exception和ErrorThrow和catchFinally总结简介Exception是程序中的异常情况,在JAVA中exception有checked Exception和unchecked Exception。那么在dart中的情况是不是一样的呢?一起来看看吧。Exception和ErrorDart中表示异常的类有两个,分别是Excep
    02-09
点击排行