From d0507481cbe3c7522722c0b075938c55787e384f Mon Sep 17 00:00:00 2001 From: yohlo Date: Sun, 23 Aug 2026 17:35:45 -0700 Subject: [PATCH] harden sse errors --- src/hooks/use-server-events.ts | 25 +++++++++++++++++++------ src/utils/supertokens-core.server.ts | 2 -- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/hooks/use-server-events.ts b/src/hooks/use-server-events.ts index 32b4a51..75cb8b9 100644 --- a/src/hooks/use-server-events.ts +++ b/src/hooks/use-server-events.ts @@ -159,16 +159,29 @@ export function useServerEvents() { logger.error("SSE connection error", error); disconnect(); + // The stream is auth-guarded, so an error is often the server rejecting + // an expired session rather than a network blip. Try to refresh; if the + // session is genuinely gone, stop retrying so we don't hammer the + // endpoint forever — a real re-login (or a wake event) will reconnect. + let sessionValid = true; + try { + const { attemptRefreshingSession } = await import('supertokens-web-js/recipe/session'); + sessionValid = await attemptRefreshingSession(); + } catch { + // Refresh call itself failed (likely offline) — treat as transient. + } + + if (disposed) return; + + if (!sessionValid) { + logger.warn("SSE stopped: session is no longer valid"); + return; + } + retryCount += 1; const delay = Math.min(1000 * Math.pow(1.5, retryCount - 1), 15000); logger.info(`SSE reconnection attempt ${retryCount} in ${Math.round(delay)}ms`); - try { - const { attemptRefreshingSession } = await import('supertokens-web-js/recipe/session'); - await attemptRefreshingSession(); - } catch { - } - reconnect(delay); }; }; diff --git a/src/utils/supertokens-core.server.ts b/src/utils/supertokens-core.server.ts index 148792a..9baec57 100644 --- a/src/utils/supertokens-core.server.ts +++ b/src/utils/supertokens-core.server.ts @@ -60,7 +60,6 @@ const verifySuperTokensSession = async (request: Request) => { const userAuthId = session?.userId; if (!userAuthId || !session) { - logger.info("No authenticated user"); return { context: { userAuthId: null, roles: [] } }; } @@ -109,7 +108,6 @@ export const getSessionContextCore = async ( } if (!session.context.userAuthId) { - logger.error("Unauthenticated user", session.context); throw new Error("Unauthenticated"); }