Dart中使用await for遍历Stream时的错误捕获及完成回调处理方法
Dart 流使用
await for转换时的错误处理方案 await for遍历流时,源流抛出的错误会直接在遍历位置触发异常,你可以通过以下两种方式处理,满足上报、调试需求:
1. 转换流内部捕获错误
直接给await for逻辑包裹try-catch块,即可捕获源流的所有错误信息,包括异常对象和调用堆栈,你可以选择抛出原始错误或者返回自定义错误事件:
// 示例Event类扩展错误类型变体 sealed class Event { const factory Event.FileChunk({required List<int> chunk}) = FileChunk; const factory Event.Completed() = Completed; const factory Event.Error({required Object error, required StackTrace stackTrace}) = Error; } Stream<Event> processResponse(HttpClientResponse response) async* { try { await for (final List<int> chunk in response) { yield Event.FileChunk(chunk: chunk); } yield const Event.Completed(); } catch (error, stackTrace) { // 此处可直接打印日志、上报错误信息 print('下载流出错:$error,调用堆栈:$stackTrace'); // 方案A:返回自定义错误事件,下游无需捕获异常,通过事件类型判断处理即可 yield Event.Error(error: error, stackTrace: stackTrace); // 方案B:重新抛出错误,由下游监听流的onError回调接收 // rethrow; } }
2. 错误交下游处理
如果你不需要在转换流内部处理错误,async*生成的流会自动透传上游的所有错误,下游监听转换后的流时,直接传入onError回调即可获取错误信息,和直接监听原始HttpClientResponse流的行为完全一致:
// 下游监听示例 final eventStream = processResponse(response); eventStream.listen( (event) { // 处理正常事件 }, onError: (e, stackTrace) { // 接收错误信息,做上报、重试等处理 }, onDone: () { // 流处理完成 }, cancelOnError: true, );
特殊场景:错误不中断流下载
如果你需要实现类似cancelOnError: false的效果,即单次分片错误不终止整个下载流程,可以先对源流做handleError预处理:
Stream<Event> processResponse(HttpClientResponse response) async* { // 预处理源流,捕获IO错误后跳过当前分片,继续下载后续内容 final processedStream = response.handleError((error, stackTrace) { print('分片下载出错,已跳过:$error'); }, test: (error) => error is IOException); await for (final List<int> chunk in processedStream) { yield Event.FileChunk(chunk: chunk); } yield const Event.Completed(); }
以上所有方式拿到的error和stackTrace都包含完整的错误类型、描述、调用链信息,完全满足上报和调试需求。
内容的提问来源于stack exchange,提问作者Mackovich
相关产品推荐
相关产品推荐

