Skip to content

Commit

Permalink
fix(fe): 🐛 pause other failed requests to wait refresh is done
Browse files Browse the repository at this point in the history
  • Loading branch information
lehuygiang28 committed Aug 25, 2024
1 parent ce4620e commit e934835
Showing 1 changed file with 36 additions and 21 deletions.
57 changes: 36 additions & 21 deletions apps/fe/src/hooks/useAxiosAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ export type UseAxiosAuthPayload =
}
| undefined;

const requestsQueue: AxiosRequestConfig[] = [];
const requestsQueue: {
prevRequest: AxiosRequestConfig;
resolve: (value: unknown) => void;
reject: (reason?: unknown) => void;
}[] = [];
let isRefreshing = false;

export function useAxiosAuth(payload?: UseAxiosAuthPayload) {
Expand Down Expand Up @@ -44,32 +48,43 @@ export function useAxiosAuth(payload?: UseAxiosAuthPayload) {

const responseIntercept = axiosInstance.interceptors.response.use(
(response) => response,
async (error) => {
(error) => {
const prevRequest = error?.config;
if (error?.response?.status === 401 && !prevRequest?.sent) {
prevRequest.sent = true;
// Queue the request
requestsQueue.push(prevRequest);
prevRequest.sent = true; // prevent infinite loop

// Create a Promise to pause the request
const retryOriginalRequest = new Promise((resolve, reject) => {
// Queue the request with its resolve/reject handlers
requestsQueue.push({ resolve, reject, prevRequest });
});

if (!isRefreshing) {
isRefreshing = true;
try {
await refreshToken();
refreshToken()
.then(() => {
// Retry all queued requests
for (const { resolve, prevRequest } of requestsQueue) {
prevRequest.headers['Authorization'] =
`Bearer ${session?.user?.accessToken}`;
resolve(axiosInstance(prevRequest));
}
})
.catch((refreshError) => {
// Handle refresh token error
for (const { reject } of requestsQueue) {
reject(error);
}

for (const queuedRequest of requestsQueue) {
queuedRequest.headers['Authorization'] =
`Bearer ${session?.user?.accessToken}`;
axiosInstance(queuedRequest);
}

requestsQueue.length = 0; // Clear the queue
} catch (refreshError) {
// Handle refresh token error
console.error('Failed to refresh token:', refreshError);
} finally {
isRefreshing = false;
}
console.error('Failed to refresh token:', refreshError);
})
.finally(() => {
requestsQueue.length = 0; // Clear the queue
isRefreshing = false;
});
}
return axiosInstance(prevRequest);

return retryOriginalRequest; // Return the Promise to pause the original request
}
return Promise.reject(error);
},
Expand Down

0 comments on commit e934835

Please sign in to comment.