Flutter入门-Dart语法6-异常机制

196 阅读3分钟

Dart中表示异常的类有两个,分别是Exception和Error

Exception是由VM或者dart code中抛出的。 Exception主要用来表示用户程序编写过程中产生的异常,是可以定位到的可以解决的异常。通常来说Exception中包含了足够的信息来方便用户来定位异常点。所以Exception通常是需要被catch的。但是和java不同的是,dart中所有的异常都是unchecked 异常,也就是说dart中的异常并不强制要求被捕获,是否捕获异常是由程序员自行决定的。构造一个异常很简单,如下所示:

Exception("message")

但是dart并不推荐这样使用,因为这样构造的异常太过通用了,即使捕获到这样的异常,可以获得信息也比较少。所以dart推荐抛出自定义异常,也就是说根据业务需要去创建Exception对应的类,然后根据业务需要进行抛出。

和JAVA一样,dart中的Error表示的是一个严重的错误,Error是应该在程序编写过程中需要避免的。dart中的Error并不需要被捕获,因为发生了Error就表示程序出现了非常严重的错误,已经无法运行下去了。所以Error是我们在程序编写过程中需要避免的

基本使用

try / on / catch

try块包裹可能出现异常的代码。
需要指定异常类型时使用on块。
catch块捕获异常对象,进而进行处理。

try {
  someException();
} on OutOfIndexException {
  // 捕获特定的异常
  doSomething();
} on Exception catch (e) {
  // 捕获其他的Exception
  print('其他的异常: $e');
} catch (e) {
  // 处理剩下的异常
  print('剩下的异常: $e');
}
try {
} catch (e, s) {
  print('异常信息: $e');
  print('堆栈信息: $s');
}

在处理完异常之后,如果想要再将其抛出,可以使用rethrow:

void doSomething(){
    try{
    }catch (e) {
    print('get exception');
    rethrow; // rethrow这个异常
  }
}

throw

如果程序产生了异常,则可以使用Throw语句将其抛出,然后在合适的地方使用catch进行捕获。

比如我们throw一个格式异常:

throw FormatException('这是一个格式异常');

但是在dart中,不仅仅可以throw Exception或者Error,任何一个Object都可以throw出去,如下所示:

throw "这是一个异常!";

finally

和JAVA一样,dart中也有Finally,用来进行最终的处理。Finally会在所有的catch语句执行完毕之后执行:

try {
  doSomething();
} catch (e) {
  print('Error: $e'); 
} finally {
  cleanUpJob(); // 最后的清理工作
}

自定义异常

/**
 * Dart 语言提供了Exception和Error类型,以及许多预定义的子类类型
 * 也可以自定义异常,Error是程序无法恢复的严重错误,表示程序出现
 * 较严重问题,而又无法通过编程处理,只能终止程序
 * 
 * 使用try语句来捕获异常,catch语句处理异常,catch语句有两个参数
 * 一个必选的异常对象,第二个是可选的堆栈对象
 * 
 */
 
// 自定义异常
class MyException implements Exception {
  // 接收异常信息
  final String msg;
  MyException(this.msg);
  // 覆写toString方法
  @override
  String toString() {
    // TODO: implement toString
    return msg ?? 'MyException:$msg';
  }
  
}
 
void main(){
  try{
    throw '这是一个异常';
  }catch(e ,s){
    print('异常详情 $e');
    print('堆栈跟踪 $s');
  }
 
  try{
    throw FormatException();
  }on FormatException catch(e,s){
    print('异常类型:FormatException 格式转换错误');
    print('异常详情 $e');
    print('堆栈跟踪 $s');
 
    // 重新抛出异常
    rethrow;
 
  }on IntegerDivisionByZeroException{
    print('异常类型:IntegerDivisionByZeroException');
  }finally{
    print('无论是否有异常,都会执行');
  }
 
  // 抛出自定义异常
  throw MyException('自定义异常');
}

常见异常

种类描述
DeferredLoadException延迟加载异常
FormatException格式异常
IntegerDivisionByZeroException整数除零异常
IOExceptionIO异常
IsolateSpawnException隔离产生异常
OSError操作系统异常
TimeoutException超时异常

异步异常

1.使用Future提供的catchError语句来进行捕获;

//使用catchError捕获异步异常 Future.delayed(Duration(seconds: 1)) .then( (e) => throw StateError('This is first Dart exception in Future.')) .catchError((e) => print(e)); 2.将异步转同步然后通过try-catch进行捕获;

```dart
try {
  await Future.delayed(Duration(seconds: 1)).then(
      (e) => throw StateError('This is second Dart exception in Future.'));
} catch (e) {
  print(e);
}
```

3.stream 流错误处理:在处理流时,你可以使用 listen() 方法来分别处理数据和错误

stream.listen(
  (data) {
    // 处理数据
  },
  onError: (error) {
    // 处理错误
    print('Error in stream: $error');
  },
  onDone: () {
    // 流关闭
  },
);