如何在catch代码块中获取Dio请求的onResponse.statusCode
解决方法
核心问题原因
- 你当前使用的
OSError.noErrorCode是类的静态常量,固定值为-1,没有从捕获到的异常实例中获取真实错误信息 - Dio将所有请求相关异常封装为
DioError类型,你没有对异常类型做区分,无法区分网络异常、服务端响应异常等场景 - 后端返回的4xx类业务异常(如凭证无效)默认会被Dio封装到
DioError.response属性中,不需要在try块的正常返回逻辑中处理
修改后代码
var data = {}; Future login() async { Dio dio = Dio(); try { data = { 'username': user.username, 'password': user.password, 'date': formattedDate }; // 无需混合使用await和then,直接接收响应结果 final response = await dio.post( localhostUrlLogin, data: json.encode(data), ); // 请求成功跳转页面 if (response.statusCode == 200) { Navigator.push( context, MaterialPageRoute(builder: (context) => const Navigation()), ); } } catch (e) { // 先判断是否是Dio请求异常 if (e is DioError) { switch (e.type) { // 连接类异常:无网络、服务未启动无法建立连接的情况 case DioErrorType.connectionTimeout: case DioErrorType.sendTimeout: case DioErrorType.receiveTimeout: case DioErrorType.connectionError: showDialog( context: context, builder: (BuildContext context) { return AdvanceCustomAlert( title: "无网络连接", descriptions: "请检查网络后重试", icon: Icons.error, bgcolor: Colors.red, fgcolor: Colors.red, ); }, ); break; // 收到服务端响应,但状态码非2xx case DioErrorType.badResponse: final statusCode = e.response?.statusCode; // 401对应凭证无效,可根据后端实际约定的状态码调整 if (statusCode == 401) { showDialog( context: context, builder: (BuildContext context) { return AdvanceCustomAlert( title: "凭证无效", descriptions: "用户名或密码错误,请重试", icon: Icons.error, bgcolor: Colors.red, fgcolor: Colors.red, ); }, ); } // 5xx对应服务端错误,服务未运行/宕机场景 else if (statusCode != null && statusCode >= 500) { showDialog( context: context, builder: (BuildContext context) { return AdvanceCustomAlert( title: "服务不可用", descriptions: "服务未运行,请稍后再试", icon: Icons.error, bgcolor: Colors.red, fgcolor: Colors.red, ); }, ); } break; // 其他未知异常 case DioErrorType.unknown: // 这里才需要从异常实例拿OSError的错误码 if (e.error is OSError) { OSError osError = e.error as OSError; // 可根据实际业务需要处理osError.errorCode } showDialog( context: context, builder: (BuildContext context) { return AdvanceCustomAlert( title: "未知错误", descriptions: "请求失败,请稍后重试", icon: Icons.error, bgcolor: Colors.red, fgcolor: Colors.red, ); }, ); break; default: break; } } else { // 非Dio异常的其他异常处理 print(e); } } }
补充说明
如果你的后端是返回200状态码,再通过响应体里的自定义业务码来判断凭证无效,只需要在try块拿到response之后,解析response.data里的业务码,判断后直接弹出对应提示即可。
内容的提问来源于stack exchange,提问作者TimeToCode
相关产品推荐
相关产品推荐

