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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 07:05:21