如何在RTK中正确处理Axios错误并完成类型转换?
问题描述
我有一个基于Axios的请求服务,其login方法代码如下:
async login(query: LoginQuery) { return await axios .get<UserModel>(`${this._apiPath}${API_PATH.AUTH}${AUTH_API.LOGIN}`, { params: query, headers: { 'Content-Type': 'application/json' } }) .then(userData => userData.data) .catch((error: AxiosError) => { if (axios.isAxiosError(error) && error.response) { throw new Error(error.response.data) } }) } export type UserModel = { token: string, name: string, email: string }
该方法返回联合类型Promise<void | UserModel>。
我的RTK(Redux Toolkit)函数代码如下:
export type ServerError = {statusCode: number, message: string, error: string} export const login = createAsyncThunk< UserModel, LoginQuery, { rejectWithValue: ServerError extra: { service: { Auth: AuthService } } } >( AuthActionType.LOGIN, async (userData: LoginQuery, { rejectWithValue, extra: { service: { Auth } } }) => { return await Auth.login(userData) .then(userResponse => userResponse) .catch((error: ServerError) => rejectWithValue(error)) } )
此时出现类型错误提示:Type 'void | UserModel | RejectWithValue<unknown, unknown>' is not assignable to type 'UserModel'。需要解决在RTK中正确处理Axios错误并完成类型转换的问题,尝试通过抛出不同错误类型来修复。
解决方案
1. 修正AuthService的login方法错误处理逻辑
当前login方法的catch块仅在error.response存在时抛出错误,其他场景(如网络错误、请求未送达服务器)会默认返回void,这是返回类型包含void的核心原因。同时,直接抛出Error实例会丢失服务器返回的结构化错误数据,需改为抛出符合ServerError类型的对象:
async login(query: LoginQuery): Promise<UserModel> { try { const userData = await axios.get<UserModel>( `${this._apiPath}${API_PATH.AUTH}${AUTH_API.LOGIN}`, { params: query, headers: { 'Content-Type': 'application/json' } } ); return userData.data; } catch (error) { if (axios.isAxiosError(error)) { // 处理服务器返回的结构化错误 if (error.response) { throw error.response.data as ServerError; } // 处理无响应的网络类错误 throw { statusCode: 0, message: '网络请求失败,请检查连接', error: 'Network Error' } as ServerError; } // 处理其他未知错误 throw { statusCode: 500, message: '未知错误', error: 'Unknown Error' } as ServerError; } }
修改后,login方法的返回类型固定为Promise<UserModel>,所有错误都会被转换为ServerError类型抛出,消除了void类型的隐患。
2. 调整RTK的createAsyncThunk错误捕获逻辑
现在login方法只会抛出ServerError类型的错误,可直接在thunk中用try/catch捕获并通过rejectWithValue返回:
export type ServerError = {statusCode: number, message: string, error: string} export const login = createAsyncThunk< UserModel, LoginQuery, { rejectWithValue: ServerError extra: { service: { Auth: AuthService } } } >( AuthActionType.LOGIN, async (userData: LoginQuery, { rejectWithValue, extra: { service: { Auth } } }) => { try { return await Auth.login(userData); } catch (error) { return rejectWithValue(error as ServerError); } } )
改用try/catch替代Promise链式调用,逻辑更直观;通过类型断言确保错误符合ServerError类型,彻底解决类型不匹配的问题。
内容的提问来源于stack exchange,提问作者Stan Wolf
相关产品推荐
相关产品推荐

