Skip to content

Commit d3db9aa

Browse files
authored
fix: handle 401 errors to trigger auth modal (#26)
* feat: enhance error handling in API utilities - Added a new function to handle unauthorized errors by updating the auth state in the query cache, triggering the AuthModal. - Updated the existing response handling to incorporate the new unauthorized error handling. - Improved clarity in the response handling logic for different status codes, including 204 and JSON responses. * refactor: rename cacheTime to gcTime in queryClient configuration - Updated the queryClient configuration to rename the cacheTime property to gcTime for clarity, indicating its purpose more accurately as garbage collection time.
1 parent 8c4461c commit d3db9aa

File tree

3 files changed

+37
-18
lines changed

3 files changed

+37
-18
lines changed

src/frontend/src/api/apiUtils.ts

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,39 @@
1+
import { queryClient } from './queryClient';
2+
3+
/**
4+
* Handle unauthorized errors by updating the auth state in the query cache
5+
* This will trigger the AuthModal to appear
6+
*/
7+
export function handleUnauthorized() {
8+
// Set auth state to false to trigger the AuthModal
9+
queryClient.setQueryData(['auth'], false);
10+
}
11+
112
// Common error handling for API responses
213
export async function handleResponse(response: Response) {
3-
if (!response.ok) {
4-
if (response.status === 401) {
5-
throw new Error('Unauthorized');
6-
}
7-
8-
const errorText = await response.text();
9-
throw new Error(errorText || `API error: ${response.status}`);
14+
if (!response.ok) {
15+
if (response.status === 401) {
16+
// Update auth state when 401 is encountered
17+
handleUnauthorized();
18+
throw new Error('Unauthorized');
1019
}
1120

12-
// For endpoints that return no content
13-
if (response.status === 204) {
14-
return null;
15-
}
16-
17-
// For endpoints that return JSON
18-
return response.json();
21+
const errorText = await response.text();
22+
throw new Error(errorText || `API error: ${response.status}`);
1923
}
2024

21-
// Base fetch function with error handling
22-
export async function fetchApi(url: string, options?: RequestInit) {
25+
// For endpoints that return no content
26+
if (response.status === 204) {
27+
return null;
28+
}
29+
30+
// For endpoints that return JSON
31+
return response.json();
32+
}
33+
34+
// Base fetch function with error handling
35+
export async function fetchApi(url: string, options?: RequestInit) {
36+
try {
2337
const response = await fetch(url, {
2438
...options,
2539
credentials: 'include',
@@ -30,4 +44,8 @@ export async function handleResponse(response: Response) {
3044
});
3145

3246
return handleResponse(response);
33-
}
47+
} catch (error) {
48+
// Re-throw the error after handling it
49+
throw error;
50+
}
51+
}

src/frontend/src/api/hooks.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export const api = {
6060
// Map backend 'state' property to frontend 'status'
6161
return { ...result, status: result.state };
6262
} catch (error) {
63+
// Let the error propagate to be handled by the global error handler
6364
throw error;
6465
}
6566
},

src/frontend/src/api/queryClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export const queryClient = new QueryClient({
77
retry: 1,
88
refetchOnWindowFocus: true,
99
staleTime: 30000, // 30 seconds
10-
cacheTime: 1000 * 60 * 5, // 5 minutes
10+
gcTime: 1000 * 60 * 5, // 5 minutes (formerly cacheTime)
1111
refetchOnMount: true,
1212
},
1313
},

0 commit comments

Comments
 (0)