You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 08:48:04