排查:Vuex中API请求为何无法进入Try/Catch块?
Vuex中Axios请求404无法进入try-catch捕获问题解决
问题描述
在Vuex开发时,发起API GET请求预期返回404错误,但执行var rptReq = await investigacionApi.get(url);时无法进入try-catch块,嵌套两层try-catch也无法解决。Postman测试相同场景能收到带响应体的404,但控制台显示该行报错。
相关代码
Vuex Action代码:
export const getUserByEmail = async ({ commit }, { dni, password }) => { var path = `/api/usuarios/dni`; try { const params = { dni, password }; const url = `${path}?${new URLSearchParams(params)}`; console.log(url) try { var rptReq = await investigacionApi.get(url); console.log(rptReq) if (!rptReq || !rptReq.data) { throw new Error('La respuesta recibida es inválida'); } const { status, data } = rptReq.data; commit('setUserProvider', { status, data, message: null }) } catch (errores) { const { status, error } = errores.response.data; commit('setUserProvider', { status, data: null, message: error }) } } catch (error) { console.log(error); commit('setUserProvider', { status: false, data: null, message: "error.message" }) } }
Axios实例代码:
import axios from 'axios' const apiUrl = process.env.VUE_APP_API_URL; const investigacionApi = axios.create({ baseURL: apiUrl }) export default investigacionApi
解决步骤
1. 确认Axios的错误触发配置
Axios默认仅将2xx范围内的状态码视为请求成功,4xx/5xx会抛出错误进入catch块。如果你的实例被修改过validateStatus配置,可能导致404不触发错误。可以显式恢复默认配置:
const investigacionApi = axios.create({ baseURL: apiUrl, validateStatus: function (status) { return status >= 200 && status < 300; // 仅2xx视为成功,其他状态码触发错误 } })
2. 修复catch块中的潜在报错
内层catch中直接访问errores.response.data存在风险:如果是网络错误(无服务器响应),errores.response会是undefined,此时访问data会抛出新错误,导致你误以为原404未被捕获。修改catch逻辑:
catch (error) { let status = false; let message = "请求失败"; if (error.response) { // 服务器返回了错误响应(包括404) const { status: resStatus, error: errMsg } = error.response.data; status = resStatus; message = errMsg; } else if (error.request) { // 请求已发送但无响应 message = "无响应,请检查网络"; } else { // 请求配置或其他错误 message = error.message; } commit('setUserProvider', { status, data: null, message }); console.error("请求详情:", error); }
3. 简化try-catch结构
嵌套try-catch完全没必要,一层即可覆盖所有错误场景,简化后更易排查问题:
export const getUserByEmail = async ({ commit }, { dni, password }) => { const path = `/api/usuarios/dni`; const params = { dni, password }; const url = `${path}?${new URLSearchParams(params)}`; console.log(url); try { const rptReq = await investigacionApi.get(url); console.log(rptReq); if (!rptReq || !rptReq.data) { throw new Error('La respuesta recibida es inválida'); } const { status, data } = rptReq.data; commit('setUserProvider', { status, data, message: null }); } catch (error) { let status = false; let message = error.message; if (error.response) { const { status: resStatus, error: errMsg } = error.response.data; status = resStatus; message = errMsg; } commit('setUserProvider', { status, data: null, message }); console.error("请求错误:", error); } };
4. 确保Action调用时的错误处理
在调用该Vuex Action的地方,也要做好错误捕获,避免未捕获的Promise rejection:
// 示例:在组件中调用Action async handleLogin() { try { await this.$store.dispatch('getUserByEmail', { dni: this.dni, password: this.password }); } catch (err) { console.error("登录操作出错:", err); } }
内容的提问来源于stack exchange,提问作者Kevin Montañez Huamán
相关产品推荐
相关产品推荐

