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
相关产品推荐
相关产品推荐

