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

Redux Toolkit正确错误处理:如何让API错误进入rejected而非fulfilled分支

问题解答

核心原因

你遇到的这个现象是因为常用请求库的默认逻辑:只有网络中断、跨域、DNS解析失败这类底层异常才会触发Promise.reject,4xx/5xx这类HTTP业务错误默认不会被标记为请求失败,因此createAsyncThunk会把接口返回的业务错误也判定为请求成功,进入fulfilled分支。

解决方案

方案1:调整thunk逻辑让错误直接进入rejected分支(更推荐)

利用createAsyncThunk内置的rejectWithValue工具手动抛出业务错误即可,示例代码如下:

const login = createAsyncThunk('user/login', async (loginParams, { rejectWithValue }) => {
  try {
    const response = await fetch('/api/login', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(loginParams)
    })
    // 手动判断HTTP状态码是否符合预期
    if (!response.ok) {
      const errorInfo = await response.json()
      // 手动返回reject状态,携带后端返回的错误信息
      return rejectWithValue(errorInfo)
    }
    return await response.json()
  } catch (error) {
    // 捕获网络层异常,同样返回reject状态
    return rejectWithValue(error.message || '请求异常')
  }
})

调整后你原有extraReducers的rejected分支就可以正常接收所有错误信息,不需要在fulfilled分支额外加判断逻辑,代码职责拆分更清晰,后续维护成本更低。
如果你用的是Axios作为请求库,默认配置下4xx/5xx会自动触发Promise.reject,不需要额外做以上处理,要是你之前修改了validateStatus配置允许非2xx状态进入resolve,把该配置改回默认值即可。

方案2:在fulfilled分支判断响应码

如果暂时不想调整thunk的实现逻辑,也可以在fulfilled分支内手动判断返回的响应码,不符合预期时手动给错误字段赋值,示例如下:

builder.addCase(login.fulfilled, (state, {payload}) => {
  // 假设返回结构里code字段为200代表业务成功
  if (payload.code !== 200) {
    state.fetchingUser = false
    state.fetchingError = payload.msg
    return
  }
  state.user = payload.data.user
  state.fetchingUser = false
});

这种方案实现简单,但错误处理逻辑分散在两个分支,不符合单一职责原则,不建议长期使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 04:30:00