Zim
Zim

Reputation: 396

AxiosBaseQuery error handling in RTK-Query

I have a simple AxiosBaseQuery very similar to the one provided in the docs: https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#axios-basequery

Specifically, in the catch block, you can see that status and data are being returned in case of an error.

   } catch (axiosError) {
      let err = axiosError as AxiosError
      return {
        error: {
          status: err.response?.status,
          data: err.response?.data || err.message,
        },
      }
    }

Now, this is my basequery which calls the axiosBaseQuery to do some header manipulation:

export const baseQuery: BaseQueryFn<IBaseQuery,
  unknown,
  unknown> = async ({ url, method, data, params }, api, extraOptions) => {
  const token = (api.getState() as any).auth.token;

  const rawBaseQuery =  axiosBaseQuery({
    baseUrl: '/',
    headers: (headers) => {
        if (token) {
            headers["Authorization"] = `Bearer ${token}`;
        }
        return headers
    }
  })

  return rawBaseQuery({ url, method, data, params }, api, extraOptions);
 
};

And then I call the baseQuery to add ReAuthentication logic:

export const baseQueryWithReauth = async (args: IBaseQuery, api: BaseQueryApi, extraOptions: {}) => {
  let result = await baseQuery(args, api, extraOptions)

  if (result?.error) {
    console.log("error", result.error)
    if (result.error.status == "403") {
      console.log('sending refresh token')
      // send refresh token to get new access token 
      // other reAuth logic
    }
  }

  return result
}

The problem is that typescript is complaining that it can't find status. When I try to console.log result, I can see that the property does exist.

I'm trying to apply the suggested ReAuth logic stated here: https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#automatic-re-authorization-by-extending-fetchbasequery

Should I be using FetchBaseQueryError instead of Unknown in AxiosBaseQuery? What is the proper way to handle the error from AxiosBaseQuery? Sorry, I'm still wrapping my head around RTK-Query and React Native.

enter image description here

Upvotes: 1

Views: 6501

Answers (1)

Linda Paiste
Linda Paiste

Reputation: 42228

The BaseQueryFn type which you are using has a whole bunch of generics:

export type BaseQueryFn<
  Args = any,
  Result = unknown,
  Error = unknown,
  DefinitionExtraOptions = {},
  Meta = {}
>

You are using BaseQueryFn<IBaseQuery, unknown, unknown> which means that the type for Error (third position) is unknown.

I looked at the doc that you linked and I see that the example is using unknown for the error as well. Maybe I should fix that :)

Based on what you are returning:

error: {
  status: err.response?.status,
  data: err.response?.data || err.message,
},

You can see that your error type should be:

{ status: number; data: any }

or, if you want to be stricter:

{ status: number; data: unknown }

So the type for your base query should be something like this:

export const baseQuery: BaseQueryFn<IBaseQuery,
  unknown,
  { status: number; data: any }
> = async () => ...

Or, with some exported types:

export type BaseQueryError = { status: number; data: any };

export type BaseQuery = BaseQueryFn<IBaseQuery, unknown, BaseQueryError>;

export const baseQuery: BaseQuery = async () => ...

Upvotes: 1

Related Questions