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

Vite React中AxiosError无法触发Catch块的问题解决

问题:Vite React项目中Axios错误状态码未触发Catch块

在Vite构建的React项目中,使用Axios向Express后端发送登录请求时,后端返回错误状态码(如500、400),Axios的Catch块并未执行。控制台能打印出AxiosError信息(示例:Login response: AxiosError {message: 'Request failed with status code 500', name: 'AxiosError', code: 'ERR_BAD_RESPONSE', ...}),但Catch逻辑完全没触发。此前使用Create React App时无此问题。

前端代码

const login = async (inputs) => {
  try {
    const res = await axios.post("/api/auth/login", inputs);
    console.log("Login response:", res);
    if (res.status === 200) {
      setCurrentUser(res.data);
      localStorage.setItem("user", JSON.stringify(res.data));
    }
    return res; // Return the response
  } catch (error) {
    console.log("Login error:", error);
    console.error("Login error:", error);
    return error.response; // Return the error response
  }
};

后端Express代码

export const login = (req, res) => {
  //CHECK USER

  const schoolNo = parseInt(req.body.schoolNo, 10);
  const studentNo = parseInt(req.body.studentNo, 10);
  

  const q = "SELECT * FROM users u WHERE u.Okul_Kodu = ? AND u.Ogrenci_No = ?";

  db.query(q, [schoolNo, studentNo], (err, data) => {
    if (err) return res.status(500).json(err);
    if (data.length === 0)
      return res.status(500).json(err);
     (data[0]);

    // Check password
    const isPasswordCorrect = bcrypt.compareSync(
      req.body.password,
      data[0].Password
    );

    if (!isPasswordCorrect)
      return res.status(400).json("Wrong username or password!");

    // Extract only the desired fields from the data
    const {
      Okul_Kodu,
      Ogrenci_No,
      Ogrenci_Adi,
      User_Role,
      Okul_Turu,
      id,
      sinif,
    } = data[0];

    const accessToken = generateAccessToken(data);
    // const refreshToken = generateRefreshToken(data);
    // refreshTokens.push(refreshToken);
    //  ("login"+refreshToken);

    // Create a response object with the desired fields
    const responseObject = {
      id,
      Okul_Kodu,
      Ogrenci_No,
      Ogrenci_Adi,
      User_Role,
      Okul_Turu,
      accessToken,
      sinif,
    };

    res
      .cookie("access_token", accessToken, {
        httpOnly: true,
      })
      .status(200)
      .json(responseObject);
  });
};

解决方案

1. 检查Axios的validateStatus配置

Axios默认仅在HTTP状态码处于200-299范围时resolve请求,非2xx状态码会抛出错误进入catch块。如果项目中Axios被全局修改了validateStatus配置(比如设置为() => true),所有响应都会被resolve,不会触发catch。

检查Axios实例创建代码,确保配置符合预期:

// 保持默认规则的配置示例
const axiosInstance = axios.create({
  validateStatus: function (status) {
    return status >= 200 && status < 300; // 非2xx状态码抛出错误
  }
});

2. 排查Vite代理的状态码修改

Vite代理配置如果存在修改响应状态码的逻辑,会把后端的错误状态码强制转为200,导致Axios判定请求成功。检查vite.config.js中的代理设置:

// vite.config.js
export default defineConfig({
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:3001',
        changeOrigin: true,
        // 移除任何修改状态码的代码,比如:
        // onProxyRes: (proxyRes) => { proxyRes.statusCode = 200; }
      }
    }
  }
});

3. 修复后端错误响应的无效参数

后端代码中,当data.length === 0时返回res.status(500).json(err),此时err为undefined(该分支是查询无结果而非查询报错),会导致响应体异常,可能干扰Axios的错误判定。修改为:

if (data.length === 0)
  return res.status(404).json("User not found!"); // 返回明确的错误信息

4. 手动在Try块中判断状态码

如果以上方案无效,可在try块中主动校验响应状态码,手动抛出错误:

const login = async (inputs) => {
  try {
    const res = await axios.post("/api/auth/login", inputs);
    // 非2xx状态码主动抛出错误
    if (res.status < 200 || res.status >= 300) {
      throw new Error(`Request failed with status code ${res.status}`);
    }
    console.log("Login response:", res);
    setCurrentUser(res.data);
    localStorage.setItem("user", JSON.stringify(res.data));
    return res;
  } catch (error) {
    console.log("Login error:", error);
    console.error("Login error:", error);
    return error.response || error;
  }
};

内容的提问来源于stack exchange,提问作者M.Mustafa ÖZAYDIN

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 18:55:14