Open
Description
I have implemented the reauthorization process with RTK Query following the docs:
This is api.ts a single createApi instance in the app:
import { createApi } from '@reduxjs/toolkit/query/react';
import { baseQueryWithReauth } from './utils';
export const api = createApi({
reducerPath: 'api',
baseQuery: baseQueryWithReauth,
endpoints: (builder) => ({}),
});
And this is what i followed, the only thing that differs is
import { fetchBaseQuery } from '@reduxjs/toolkit/query'
import type {
BaseQueryFn,
FetchArgs,
FetchBaseQueryError,
} from '@reduxjs/toolkit/query'
import { tokenReceived, loggedOut } from './authSlice'
import { Mutex } from 'async-mutex'
// create a new mutex
const mutex = new Mutex();
const baseQuery =
fetchBaseQuery({
baseUrl: `${process.env.BASE_URL}`,
prepareHeaders: (headers: Headers) => generateHeadersIfAny(headers),
}),
const baseQueryWithReauth: BaseQueryFn<
string | FetchArgs,
unknown,
FetchBaseQueryError
> = async (args, api, extraOptions) => {
// wait until the mutex is available without locking it
await mutex.waitForUnlock()
let result = await baseQuery(args, api, extraOptions)
if (result.error && result.error.status === 401) {
// checking whether the mutex is locked
if (!mutex.isLocked()) {
const release = await mutex.acquire()
try {
const refreshResult = await baseQuery(
'/get-new-tokens',
api,
extraOptions
)
if (refreshResult.data) {
api.dispatch(tokenReceived(refreshResult.data))
// retry the initial query
result = await baseQuery(args, api, extraOptions)
} else {
api.dispatch(loggedOut())
}
} finally {
// release must be called once the mutex should be released again.
release()
}
} else {
// wait until the mutex is available without locking it
await mutex.waitForUnlock()
result = await baseQuery(args, api, extraOptions)
}
}
return result
}
And this example works perfectly when refresh token did not expire and your refetch route returns 200 and new tokens, but the problem is when your refresh route returns 401 or 400 it goes in the else of if/else but it reruns all the requests that got 401. It's like it only works in the most optimistic case. I would like if my get-new-tokens route returns 400 or 401 don't rerun any of the multiple requests you have in mutex.