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

Fetch API错误处理问题:无法正确获取API返回的错误信息

解决Fetch处理API错误的两难问题

我太懂你这个困扰了——用fetch处理API返回的业务错误时,确实容易陷入“要么抓不到API错误,要么误触发成功action”的两难。咱们先理清楚问题根源,再给你一个靠谱的解决方案。

问题根源

fetch的设计很“特殊”:只有当网络层面彻底失败(比如断网、域名解析失败)时,才会自动抛出错误进入catch。哪怕API返回401、400这类业务错误状态码,fetch都会认为请求“成功”,直接进入.then流程。

  • 你第一段代码里throw response,抛出去的是Response对象,不是API返回的错误JSON,所以catch里拿到的不是后端给的具体错误信息;
  • 第二段代码跳过response.ok判断,不管状态码如何都解析JSON然后走成功action,哪怕后端返回的是错误内容。

正确的处理方式

核心思路是:先统一解析响应体,再根据状态码或返回内容判断是成功还是失败,把API返回的错误JSON主动抛进catch里。

修改后的代码如下:

export const signIn = data => dispatch => {
  dispatch({ type: SIGN_IN });
  fetch(`${API_URL}/login`, {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify(data),
  })
  .then(response => {
    // 先解析响应体,不管状态码是否正常
    return response.json().then(json => {
      // 如果状态码非2xx,把解析后的错误JSON抛出去
      if (!response.ok) {
        throw json;
      }
      // 状态码正常,返回成功数据
      return json;
    });
  })
  .then(json => {
    dispatch({ type: SIGN_IN_SUCCESS, payload: json });
    localStorage.setItem("token", 'Bearer ' + json.token);
    localStorage.setItem("user", JSON.stringify(json.user));
  })
  .catch(err => {
    // 这里的err要么是网络错误,要么是API返回的错误JSON
    dispatch({ type: SIGN_IN_FAILED, payload: err });
  });
};

额外优化点

如果你的后端习惯用200状态码,但通过返回体里的字段(比如success: false或code: 400)标识错误,那可以把判断逻辑换成基于返回内容:

.then(response => response.json())
.then(json => {
  // 假设后端用success字段标识请求是否成功
  if (!json.success) {
    throw json;
  }
  return json;
})

这样不管后端用什么状态码,都能准确捕获业务错误,同时只有真正成功时才会触发登录成功的action。

内容的提问来源于stack exchange,提问作者Merim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:37:39