如何使用Ferry GraphQL处理请求错误并正确获取响应错误信息
问题根因
- Ferry客户端的
request()方法返回的是*Stream*类型,你直接用 listen注册回调属于异步监听,函数不会等待回调执行完成就会提前返回_result,所以永远拿不到请求后的真实结果。 - 你手动实例化的空
OperationResponse对象没有关联真实的请求返回数据,自然读取不到错误信息。
修复方案
方案1:用Stream的first属性等待首个返回结果
适合普通单次网络请求场景,直接改造sendLogin方法如下:
Future<String> sendLogin(String _email, String _password) async { final _sendLoginRequest = GLoginReq((b) => b ..vars.identifier = _email ..vars.password = _password); final _client = initClient(); // 等待Stream返回第一个响应结果 final response = await _client.request(_sendLoginRequest).first; if (response.hasErrors) { // 解析Strapi返回的具体业务错误信息 final firstError = response.graphqlErrors?.first; if (firstError != null) { final errorMsg = firstError.extensions?['exception']?['data']?['message']?[0]?['messages']?[0]?['message'] ?? '未知登录错误'; print('登录错误:$errorMsg'); } return 'error'; } else { // 登录成功后可在此处添加存储token等逻辑 return 'success'; } }
方案2:用await for遍历Stream
适合配置了缓存优先策略、需要处理多段响应的场景:
Future<String> sendLogin(String _email, String _password) async { final _sendLoginRequest = GLoginReq((b) => b ..vars.identifier = _email ..vars.password = _password); final _client = initClient(); await for (final response in _client.request(_sendLoginRequest)) { if (response.hasErrors) { final errorMsg = response.graphqlErrors?.first?.extensions?['exception']?['data']?['message']?[0]?['messages']?[0]?['message'] ?? '未知登录错误'; print('登录错误:$errorMsg'); return 'error'; } // 跳过缓存响应,只返回网络请求的成功结果 if (!response.dataSource.isFromCache) { return 'success'; } } return 'error'; }
优化建议
你可以把解析到的具体错误信息直接返回给上层调用方,无需只返回error/success标识,上层可以直接将错误提示展示给用户:
// 上层调用示例 try { final loginResult = await toLogin(_email, _password); if (loginResult == 'success') { // 跳转至首页 } else { // 展示loginResult中携带的错误提示 } } catch(e) { // 处理网络异常、请求超时等其他错误 }
内容的提问来源于stack exchange,提问作者dmitry.kurakin kurakin
相关产品推荐
相关产品推荐

