fix(auth): prevent concurrent dispatch deadlocks and add timeout to UserContext
This commit is contained in:
parent
6640162d4d
commit
8502a82b5a
1 changed files with 23 additions and 7 deletions
|
|
@ -87,13 +87,30 @@ export const UserProvider: React.FC<{ children: ReactNode }> = ({ children }) =>
|
|||
|
||||
useEffect(() => {
|
||||
let mounted = true;
|
||||
let isFetching = false; // Prevent concurrent deadlocks
|
||||
|
||||
const handleSession = async (session: any) => {
|
||||
if (isFetching) return;
|
||||
isFetching = true;
|
||||
|
||||
if (session?.user) {
|
||||
await fetchUserProfile(session.user.id, session.user.email);
|
||||
// Promise.race to guarantee we escape infinite loading if Supabase POST/GET hangs
|
||||
const timeout = new Promise<void>((_, reject) => setTimeout(() => reject(new Error("DB Timeout")), 8000));
|
||||
try {
|
||||
await Promise.race([
|
||||
fetchUserProfile(session.user.id, session.user.email),
|
||||
timeout
|
||||
]);
|
||||
} catch (e) {
|
||||
console.error("UserContext HandleSession Error:", e);
|
||||
if (mounted) setLoading(false);
|
||||
} finally {
|
||||
isFetching = false;
|
||||
}
|
||||
} else {
|
||||
setUser(null);
|
||||
setLoading(false);
|
||||
if (mounted) setLoading(false);
|
||||
isFetching = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -110,21 +127,20 @@ export const UserProvider: React.FC<{ children: ReactNode }> = ({ children }) =>
|
|||
setIsAdminView(false);
|
||||
setIsProfessionalView(false);
|
||||
setIsCompletingProfile(false);
|
||||
setLoading(false);
|
||||
if (mounted) setLoading(false);
|
||||
isFetching = false;
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize session manually in case INITIAL_SESSION doesn't trigger
|
||||
// (sometimes needed depending on supabase-js version and local storage state)
|
||||
// Fallback for when "INITIAL_SESSION" gets completely skipped by Supabase JS on load
|
||||
supabase.auth.getSession().then(({ data: { session }, error }) => {
|
||||
if (error) {
|
||||
console.error("UserContext: Falha na sessão inicial", error);
|
||||
if (mounted) setLoading(false);
|
||||
} else if (session) {
|
||||
// Handled gracefully: forces profile fetch if session exists but events failed
|
||||
// If there's a session but events haven't fired or were skipped, gently process it
|
||||
handleSession(session);
|
||||
} else {
|
||||
// Se não há sessão e onAuthStateChange não disparou INITIAL_SESSION
|
||||
if (mounted) setLoading(false);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue