diff --git a/web/src/toast.ts b/web/src/toast.ts index 3d51f38..2d35071 100644 --- a/web/src/toast.ts +++ b/web/src/toast.ts @@ -160,15 +160,43 @@ const setupFetchInterceptor = (): void => { window.fetch = async (...args: Parameters): Promise => { try { const response = await originalFetch(...args); - + + // Special handling for 401 Unauthorized + if (response.status === 401) { + // Clear invalid tokens from localStorage + localStorage.removeItem('token'); + localStorage.removeItem('refreshToken'); + localStorage.removeItem('user'); + + // Check if this was a page navigation (not API call) + const url = args[0] as string; + + // Don't show toast for page navigations - will be handled by redirect + if (!url.startsWith('/api/')) { + // Direct navigation to protected page will be caught by middleware + // Just throw to prevent further processing + throw new Error('Session expired'); + } + + // API call - show toast error + const errorMessage = await parseFetchError(response); + showToast(errorMessage, 'error'); + + return response; + } + + // Handle other errors if (!response.ok) { const errorMessage = await parseFetchError(response); showToast(errorMessage, 'error'); } - + return response; } catch (error) { - showToast('Network error: Unable to connect to server', 'error'); + // Don't show toast for redirect errors + if ((error as Error).message !== 'Session expired') { + showToast('Network error: Unable to connect to server', 'error'); + } throw error; } };