From c0bc9f8209f1a94d14aaf0528e2eaefe6729d825 Mon Sep 17 00:00:00 2001 From: Jakub Wilk Date: Mon, 4 Nov 2024 13:22:48 +0100 Subject: [PATCH] feat: update authentication and error handling in ApiClient and queryClient --- apps/web/app/api/api-client.ts | 43 +++++++++++++++++---------------- apps/web/app/api/queryClient.ts | 19 +++++++++++++-- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/apps/web/app/api/api-client.ts b/apps/web/app/api/api-client.ts index 030710b6..290d7c91 100644 --- a/apps/web/app/api/api-client.ts +++ b/apps/web/app/api/api-client.ts @@ -7,32 +7,33 @@ export const ApiClient = new API({ withCredentials: true, }); -ApiClient.instance.interceptors.response.use( - (response) => response, - async (error) => { - const originalRequest = error.config; +ApiClient.instance.interceptors.request.use((config) => { + const isAuthEndpoint = + config.url?.includes("/login") || + config.url?.includes("/refresh") || + config.url?.includes("/register"); - const isLoginRequest = originalRequest.url.includes("/login"); - const isRefreshRequest = originalRequest.url.includes("/refresh"); + if (!isAuthEndpoint && !useAuthStore.getState().isLoggedIn) { + const controller = new AbortController(); + controller.abort(); + config.signal = controller.signal; + } - if (error.response?.status === 401 && !originalRequest._retry) { - originalRequest._retry = true; + return config; +}); - if ( - !isLoginRequest && - !isRefreshRequest && - useAuthStore.getState().isLoggedIn - ) { - try { - await ApiClient.api.authControllerRefreshTokens(); - return ApiClient.instance(originalRequest); - } catch (refreshError) { - useAuthStore.getState().setLoggedIn(false); - return Promise.reject(refreshError); - } +ApiClient.instance.interceptors.response.use( + (response) => response, + async (error) => { + if (error.response?.status === 401 && !error.config._retry) { + error.config._retry = true; + try { + await ApiClient.api.authControllerRefreshTokens(); + return ApiClient.instance(error.config); + } catch { + useAuthStore.getState().setLoggedIn(false); } } - return Promise.reject(error); } ); diff --git a/apps/web/app/api/queryClient.ts b/apps/web/app/api/queryClient.ts index 6b529a7d..b229e32c 100644 --- a/apps/web/app/api/queryClient.ts +++ b/apps/web/app/api/queryClient.ts @@ -1,10 +1,25 @@ import { QueryClient } from "@tanstack/react-query"; -import { isAxiosError } from "axios"; +import { isAxiosError, isCancel } from "axios"; export const queryClient = new QueryClient({ defaultOptions: { queries: { - retry(failureCount, error) { + retry(failureCount, error: unknown) { + if (isCancel(error)) return false; + + if (isAxiosError(error)) { + if (error.response?.status === 401) return false; + } + + if (failureCount >= 3) return false; + + return true; + }, + }, + mutations: { + retry(failureCount, error: unknown) { + if (isCancel(error)) return false; + if (isAxiosError(error)) { if (error.response?.status === 401) return false; }