我有一个异步方法,它又调用一些其他可能引发错误的异步方法。 问题是 try-catch 只处理抛出的第一个异常。 我假设一旦函数从 future 收到错误,它就会“失败”并停止执行。因此,此后抛出的其余错误是“孤立的”,因此无法处理。如果我错了请纠正我。
这是问题的一个例子:
import 'dart:async';
Future<bool> asyncFuncThatThrows(Duration duration, String message) {
return Future.delayed(
duration, () => throw Exception('$message asyncFuncThatThrows'));
}
Future<void> asyncMethod() async {
print('asyncMethod start');
Future<bool> future1 = asyncFuncThatThrows(Duration(seconds: 0), 'first ');
Future<bool> future2 = asyncFuncThatThrows(Duration(seconds: 0), 'second ');
print('asyncMethod -> functions that throw executed');
await future1;
await future2;
print('asyncMethod done');
}
void main() {
runZoned(() async {
try {
print('Start');
await asyncMethod();
} catch (e) {
print('Try/Catch in main: $e');
}
print('Done');
});
}
这是我在终端中得到的输出(令人惊讶的是,在 DartPad 中未出现未处理的异常......奖金问题):
# dart run async_test.dart
Start
asyncMethod start
asyncMethod -> functions that throw executed
Try/Catch in main: Exception: first asyncFuncThatThrows
Done
Unhandled exception:
Exception: second asyncFuncThatThrows
#0 asyncFuncThatThrows.<anonymous closure> (file:///Users/amateo/code/flutter-projects/async_test.dart:5:23)
#1 new Future.delayed.<anonymous closure> (dart:async/future.dart:423:39)
#2 _rootRun (dart:async/zone.dart:1391:47)
#3 _CustomZone.run (dart:async/zone.dart:1301:19)
#4 _CustomZone.runGuarded (dart:async/zone.dart:1209:7)
#5 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1249:23)
#6 _rootRun (dart:async/zone.dart:1399:13)
#7 _CustomZone.run (dart:async/zone.dart:1301:19)
#8 _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:1233:23)
#9 Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
#10 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:398:19)
#11 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:429:5)
#12 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
我期望 try-catch 能够捕获所有异常。如何确保捕获异步调用引发的所有异常?
是的,问题是您正在启动两个异步操作并获得两个
Future
对象,然后您稍后开始等待第一个对象。那么问题是,第一个 Future
失败,其余的 asyncMethod()
将不会被执行,这意味着我们永远不会订阅也失败的 future2
。
Dart 然后崩溃,因为你有未处理的异步错误。
一个可能的解决方案是通过执行以下操作同时
await
两个 Future
对象:
await (future1, future2).wait;
现在,您的程序将输出以下内容,我们可以看到两个错误被收集在一起:
Start
asyncMethod start
asyncMethod -> functions that throw executed
Try/Catch in main: ParallelWaitError(2 errors): Exception: first asyncFuncThatThrows
Done
对于 DartPad,我真的不知道发生了什么,但感觉像是一个应该报告的错误。但现在再次确定。 :)