T
TanStack3mo ago
optimistic-gold

Loader and interceptors

Hi guys, I've encountered an unexpected behavior (at least for me) when using TanStack Router. When I make an asynchronous call to an API inside a loader, and the API responds with a 401 Unauthorized due to an expired access token, I expect my Axios interceptors to handle this (as they do correctly with useQuery, useMutation, etc.). However, it seems that the error is caught by the router’s error handling mechanism before the interceptor has a chance to process it. As a result, logic such as token refreshing, user sign-out, or redirecting doesn’t happen. Is this expected behavior? If so, is there a recommended pattern to allow Axios interceptors to work correctly with loader-based API calls?
24 Replies
rival-black
rival-black3mo ago
does the loader throw an error? then router will handle it
optimistic-gold
optimistic-goldOP3mo ago
Yes it does, and yes, router display it's own default errorComponent but why the interceptors are not handling error first? It looks like error handler from router does it first, before response interceptors
rival-black
rival-black3mo ago
how did you install your interceptors? you need to prevent the loader to throw an error if you handle it yourself
optimistic-gold
optimistic-goldOP3mo ago
my interceptors are installed here in authprovider in useLayoutEffect hook
No description
rival-black
rival-black3mo ago
ah well
optimistic-gold
optimistic-goldOP3mo ago
atleast those responsible for auth mechanism
rival-black
rival-black3mo ago
a loader does not execute inside of the react world so your react interceptors cannot handle that or maybe I misunderstood do you think the response interceptors are not installed yet?
optimistic-gold
optimistic-goldOP3mo ago
i think you might be right i'm installing some of interceptors here and some interceptors direct in axios instance i wanted to add possibility to interact with UI from interceptors (show snackbar for example) and this can be done only by installing interceptors in some context provider which has access to other context providers On image for example authprovider has access to things from snackbarprovider
rival-black
rival-black3mo ago
so is it a timing issue now? the interceptors not installed before the error occurs in router?
optimistic-gold
optimistic-goldOP3mo ago
i think as you said "a loader does not execute inside of the react world", so the interceptors registered in react hooks doesn't work Am i right?
rival-black
rival-black3mo ago
no i misunderstood your setup your axios instance also lives outside react kinda it is not a react managed component or depends on react rendering so if the interceptors are installed as here https://axios-http.com/docs/interceptors then I dont see a reason why the loader would throw
optimistic-gold
optimistic-goldOP3mo ago
oke so i have this axios.ts file which creates instance
export const axiosClient = axios.create({
baseURL: '/api',
headers: {
'Content-Type': 'application/json',
pragma: 'no-cache',
'cache-control': 'no-cache'
},
paramsSerializer: {
indexes: null
}
});
export const axiosClient = axios.create({
baseURL: '/api',
headers: {
'Content-Type': 'application/json',
pragma: 'no-cache',
'cache-control': 'no-cache'
},
paramsSerializer: {
indexes: null
}
});
but the interceptors are not installed here. They are installed in mentioned AuthProvider like this
export const WAuthProvider = ({ children }: PropsWithChildren<unknown>) => {
const snackbar = useSnackbar();
useLayoutEffect(() => {
const refreshInterceptor = axiosClient.interceptors.response.use(
async response => {
snackbar.show('somemessage');
}
);
return () => axiosClient.interceptors.request.eject(authInterceptor);
}
}
export const WAuthProvider = ({ children }: PropsWithChildren<unknown>) => {
const snackbar = useSnackbar();
useLayoutEffect(() => {
const refreshInterceptor = axiosClient.interceptors.response.use(
async response => {
snackbar.show('somemessage');
}
);
return () => axiosClient.interceptors.request.eject(authInterceptor);
}
}
rival-black
rival-black3mo ago
so when does the error occur? has the auth provider been rendered already?
optimistic-gold
optimistic-goldOP3mo ago
my guess is no. Because i tried to log some stuff in this provider and didn't see any log in console wait
optimistic-gold
optimistic-goldOP3mo ago
it is rendering, i put some more logs
No description
rival-black
rival-black3mo ago
but your interceptor does not prevent the error to be thrown?
optimistic-gold
optimistic-goldOP3mo ago
yep it should hit /refresh, then after achieving new token hit /orders again
optimistic-gold
optimistic-goldOP3mo ago
No description
rival-black
rival-black3mo ago
looks like you need to install two functions in the interceptor? https://axios-http.com/docs/interceptors
optimistic-gold
optimistic-goldOP3mo ago
ah sorry, i have the other one too, just didn't copy it there goddamn i noticed something but you pointed it out 😄 thanks for help, i had a very hard to find problem with interceptor logic
rival-black
rival-black3mo ago
what was the issue now?
optimistic-gold
optimistic-goldOP3mo ago
my bad, i have some weird logic on backend that api validates public request's and shows info about expired token not in error response but in header which i didn't handle properly
rival-black
rival-black3mo ago
so all working now?
optimistic-gold
optimistic-goldOP3mo ago
yes, issue closed Thanks for help

Did you find this page helpful?