Vite React中AxiosError无法触发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

