我有一个FutureBuilder小部件,该部件调用了一个异步函数,该函数旨在从远程服务器中获取给定设备可用的控件列表。
FutureBuilder<List<Control>> buildControlList() {
return FutureBuilder<List<Control>>(
future: widget.server.getResponse(widget.device, widget.controlSet),
builder:
(BuildContext context, AsyncSnapshot<List<Control>> snapshot) {
if (snapshot.hasData) {
return buildList(buildControls(widget.controlSet, snapshot.data));
} else if (snapshot.hasError) {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('${snapshot.error.toString()}')));
}
return const Center(child: CircularProgressIndicator());
});
}
getResponse函数调用另一个异步_get函数,该函数生成并执行实际的api请求。接收到响应后,它将响应数据发送到同步功能,该功能检查服务器报告的错误内容。如果找到一个,则会抛出自己的错误:
Future<List<Control>> getResponse(Device device, ControlSet controlSet,
{Map<String, dynamic> params}) async {
final String epoint = 'device/${device.name}/set/${controlSet.name}/';
final http.Response response = await _get(epoint, params: params);
_checkServerError(response); //synchronous check of response data
final List<Control> values =
json.decode(response.body).map<Control>((dynamic e) {
return Control.fromJson(e);
}).toList();
return values;
}
_checkServerError函数非常简单。我已经尝试过同步和异步两种版本,并且似乎有相同的行为。
void _checkServerError(http.Response response) {
if (response.statusCode != 200) {
final Map<String, dynamic> body = json.decode(response.body);
if (body.containsKey('error')) {
throw ServerException(
statusCode: response.statusCode, errorMsg: body['error']);
}
}
}
我似乎无法使引发的ServerException传播到FutureBuilder的snapshot.hasError检查。我不想捕获该错误并在getResponse()函数中重新抛出该错误,尽管它确实可以正常工作。将_checkServerError()更改为异步函数并等待它似乎也不起作用。
为什么错误不会继续向上延续到FutureBuilder?
编辑:调用堆栈显示源自_checkServerError()的错误,该错误向上传播至buildControlList()内的FutureBuilder。所以它到达那里。但是,FutureBuilder似乎没有捕获它并将其解释为错误的“快照”。也许我没有正确使用FutureBuilder?也来自“未知来源”。不确定如何解释。
调用堆栈:
Server._checkServerError (/mobile-client/lib/services/server.dart:75)
Server.getResponse (/mobile-client/lib/services/server.dart:112)
<asynchronous gap> (Unknown Source:0)
_ControlsScreen.buildControlList (/mobile-client/lib/screens/devices/controls.dart:71)
_ControlsScreen.build.<anonymous closure> (/mobile-client/lib/screens/devices/controls.dart:50)
Consumer.buildWithChild (/provider-4.0.5+1/lib/src/consumer.dart:175)
SingleChildStatelessWidget.build (/nested-0.0.4/lib/nested.dart:260)
StatelessElement.build (/lib/src/widgets/framework.dart:4576)
SingleChildStatelessElement.build (/nested-0.0.4/lib/nested.dart:280)
ComponentElement.performRebuild (/lib/src/widgets/framework.dart:4502)
Element.rebuild (/lib/src/widgets/framework.dart:4218)
StatelessElement.update (/lib/src/widgets/framework.dart:4583)
Element.updateChild (/lib/src/widgets/framework.dart:3201)
ComponentElement.performRebuild (/lib/src/widgets/framework.dart:4527)
Element.rebuild (/lib/src/widgets/framework.dart:4218)
StatelessElement.update (/lib/src/widgets/framework.dart:4583)
Element.updateChild (/lib/src/widgets/framework.dart:3201)
ComponentElement.performRebuild (/lib/src/widgets/framework.dart:4527)
Element.rebuild (/lib/src/widgets/framework.dart:4218)
ProxyElement.update (/lib/src/widgets/framework.dart:4862)
Element.updateChild (/lib/src/widgets/framework.dart:3201)
ComponentElement.performRebuild (/lib/src/widgets/framework.dart:4527)
Element.rebuild (/lib/src/widgets/framework.dart:4218)
ProxyElement.update (/lib/src/widgets/framework.dart:4862)
Element.updateChild (/lib/src/widgets/framework.dart:3201)
RenderObjectElement.updateChildren (/lib/src/widgets/framework.dart:5522)
MultiChildRenderObjectElement.update (/lib/src/widgets/framework.dart:5957)
Element.updateChild (/lib/src/widgets/framework.dart:3201)
ComponentElement.performRebuild (/lib/src/widgets/framework.dart:4527)
StatefulElement.performRebuild (/lib/src/widgets/framework.dart:4675)
Element.rebuild (/lib/src/widgets/framework.dart:4218)
StatefulElement.update (/lib/src/widgets/framework.dart:4707)
Element.updateChild (/lib/src/widgets/framework.dart:3201)
ComponentElement.performRebuild (/lib/src/widgets/framework.dart:4527)
Element.rebuild (/lib/src/widgets/framework.dart:4218)
ProxyElement.update (/lib/src/widgets/framework.dart:4862)
Element.updateChild (/lib/src/widgets/framework.dart:3201)
ComponentElement.performRebuild (/lib/src/widgets/framework.dart:4527)
StatefulElement.performRebuild (/lib/src/widgets/framework.dart:4675)