11import { createContext , useCallback , useContext , useEffect , useMemo , useState , type ReactNode } from 'react' ;
2- import { jwt } from '../api/client' ;
2+ import { ApiError , jwt } from '../api/client' ;
33import { authApi } from '../api/services' ;
44import type { User } from '../types' ;
55
6- export type AuthState = 'authenticated' | 'unauthenticated' | 'loading' ;
6+ export type AuthState = 'authenticated' | 'unauthenticated' | 'unavailable' | ' loading';
77
88interface UserContextValue {
99 user : User | null ;
@@ -29,20 +29,37 @@ export function UserProvider({ children }: { children: ReactNode }) {
2929 const [ user , setUserState ] = useState < User | null > ( null ) ;
3030 const [ authState , setAuthState ] = useState < AuthState > ( jwt . getToken ( ) ? 'loading' : 'unauthenticated' ) ;
3131
32+ const [ retryAttempt , setRetryAttempt ] = useState ( 0 ) ;
33+
3234 useEffect ( ( ) => {
3335 if ( ! jwt . getToken ( ) ) return ;
36+ let cancelled = false ;
3437 authApi
3538 . getCurrentUser ( )
3639 . then ( ( { user } ) => {
40+ if ( cancelled ) return ;
3741 setUserState ( user ) ;
3842 setAuthState ( 'authenticated' ) ;
3943 } )
40- . catch ( ( ) => {
41- jwt . destroyToken ( ) ;
42- setUserState ( null ) ;
43- setAuthState ( 'unauthenticated' ) ;
44+ . catch ( ( err : unknown ) => {
45+ if ( cancelled ) return ;
46+ if ( err instanceof ApiError && err . status >= 400 && err . status < 500 ) {
47+ jwt . destroyToken ( ) ;
48+ setUserState ( null ) ;
49+ setAuthState ( 'unauthenticated' ) ;
50+ } else {
51+ // Server error or network failure: keep the token and retry with backoff
52+ setAuthState ( 'unavailable' ) ;
53+ const delay = Math . min ( 1000 * 2 ** retryAttempt , 30000 ) ;
54+ setTimeout ( ( ) => {
55+ if ( ! cancelled ) setRetryAttempt ( a => a + 1 ) ;
56+ } , delay ) ;
57+ }
4458 } ) ;
45- } , [ ] ) ;
59+ return ( ) => {
60+ cancelled = true ;
61+ } ;
62+ } , [ retryAttempt ] ) ;
4663
4764 const login = useCallback ( ( user : User ) => {
4865 jwt . saveToken ( user . token ) ;
0 commit comments