在由FutureBuilder调用的异步函数中捕获同步错误

时间:2020-06-24 00:28:52

标签: flutter asynchronous dart nested

我有一个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)

0 个答案:

没有答案