fix(waiter): don't log the waiter out when the server is unreachable at startup

AuthRehydrator called logout() on ANY failure of /api/auth/me, including a
network error. So opening the app while WiFi was flaky, while the server was
restarting, or right after its IP changed silently threw the waiter back to
the login screen and offline mode could not survive an app restart. Now a
network error keeps the token and retries every 5s; a real server answer
(401 and other errors) still ends the session as before.

Verified on the Android emulator: cold start with the backend stopped keeps
the token; starting the backend brings the app to /tables on its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-28 17:00:33 +03:00
co-authored by Claude Opus 5.5
parent ee74f84c9f
commit cae5d75005
+24 -5
View File
@@ -274,12 +274,31 @@ function AppLayout() {
function AuthRehydrator() { function AuthRehydrator() {
const { token, user, login, logout } = useAuthStore() const { token, user, login, logout } = useAuthStore()
useEffect(() => { useEffect(() => {
if (token && !user) { if (!token || user) return
client.get('/api/auth/me') let cancelled = false
.then(r => login(r.data, token)) let timer = null
.catch(() => logout()) async function load() {
try {
const r = await client.get('/api/auth/me')
if (!cancelled) login(r.data, token)
} catch (err) {
if (cancelled) return
// Server unreachable (flaky WiFi, server restarting, IP change being
// rediscovered): keep the login and try again. Only a real answer from
// the server ends the session — 401 is also handled by the axios interceptor.
if (!err.response) {
timer = setTimeout(load, 5000)
return
} }
}, []) logout()
}
}
load()
return () => {
cancelled = true
clearTimeout(timer)
}
}, [token, user])
return null return null
} }