Dart嵌套async*流使用yield*时异常无法捕获的原因咨询
现象底层原因
await与yield*的异常传播逻辑存在本质差异:- 用
await调用Future时,Future抛出的异常会直接传递到当前await所在的执行上下文,因此包裹await的try-catch可以正常捕获asyncError返回的Future抛出的异常,该行为符合Dart的异步设计规范。 - 用
yield*转发Stream时,yield*的核心逻辑是原样转发目标Stream的所有事件(包括数据事件、错误事件、结束事件),错误事件不会被转换为当前async*函数的同步抛出异常,因此包裹yield*的try-catch无法捕获这类错误。
- 用
- 示例输出中出现
Uncaught Error的直接原因:调用getString().listen(print)时没有传入onError回调,yield*转发的asyncStarError错误事件没有消费端处理,触发了Dart全局未捕获错误处理逻辑。 - 若需要在当前
async*函数内捕获yield*对应Stream的异常,可以将直接yield*替换为await for遍历目标Stream,修改后的代码示例如下:
Stream<String> getString() async* { try { await for (final str in asyncStarError()) { yield str; } yield await asyncError(); } catch (err) { yield 'Crash'; } }
修改后asyncStarError抛出的异常会被try-catch正常捕获,不会再出现未捕获错误。
内容的提问来源于stack exchange,提问作者DarkNeuron
相关产品推荐
相关产品推荐

