为什么FutureBuilder的snapshot从未捕获错误?如何正确生成snapshot.error?
问题核心原因
你有两处错误导致错误无法被FutureBuilder捕获:
- 异步请求方法的返回逻辑错误:如果你的
request方法是async修饰的,async函数会自动将返回值封装为Future对象,你手动return Future.error("Error")相当于让Future成功返回了一个Future类型的错误实例,而非让当前Future进入失败状态。 - FutureBuilder的future参数存在语法和逻辑错误:
- Dart中
() => {xxx}的写法会返回Set集合,而非执行语句块,你这里实际返回的是包含request()返回值的Set对象 - 额外套的外层Future没有await内层
request()的执行结果,直接就进入完成状态,snapshot拿到的data永远是外层Future的返回值(即Set实例),自然永远不会触发hasError。
- Dart中
修复方案
第一步:修改请求方法的错误抛出逻辑
将return Future.error改为直接抛出异常即可,async方法会自动将抛出的异常转为Future的失败状态:
try { var response = await http.get(url); // Success if (response.statusCode == 200) { // 直接返回解析后的数据即可,async会自动封装为Future return yourParsedData; } // Failure else { throw "Error"; } } catch (e) { throw "Error"; }
第二步:修改FutureBuilder的future参数
去掉多余的外层Future封装,直接传入request()方法返回的Future即可:
FutureBuilder( future: Singleton().request(), builder: (context, snapshot) { // 建议先判断加载状态 if (snapshot.connectionState == ConnectionState.waiting) { return CircularProgressIndicator(); } else if(snapshot.hasError) { // 现在可以正常进入错误分支 return Text("请求错误:${snapshot.error}"); } else if (snapshot.hasData) { // 正常渲染数据 return YourDataWidget(snapshot.data); } return SizedBox.shrink(); });
修改后不需要额外加catchError回调,FutureBuilder就可以正常捕获到请求的错误状态。
内容的提问来源于stack exchange,提问作者Jumpa
相关产品推荐
相关产品推荐

