import { HttpError } from '../services/HttpService.tsx'; /** * Did the server actually answer, or did we never reach it? * * SPENCER'S RULING, 2026-08-05: "transport failure shouldn't log anyone out." * * `OrganizationCheck`'s catch (App.tsx) used to treat every failure the same way and call `logout()`, * which ends in `window.location.reload()` - so a single dropped connection during app load cleared * every token and hard-reloaded the page, for every user. That is *, and it is the same distinction spent a review round * establishing on `CredentialRevertPage` and `CredentialUnlockPage`: those two pages get it right and * the shell above them did not. * * - `refused` - the server answered and said no. Ending the session may be correct: a 401 means the * credentials are bad, and an org that genuinely is not associated with this * installation is not one this user can carry on inside. * - `unreachable` - the request never arrived. **We learned nothing**, so nothing may be destroyed on * the strength of it. * * FAILS TOWARD KEEPING THE SESSION. Anything we cannot positively identify as a server refusal is * `unreachable`, because the cost of the two mistakes is not symmetric: wrongly keeping a session shows * a retry screen, wrongly ending one can spend a patient's single-use credential-recovery token (the * revert page acts on load and burns its token before doing anything else). * * `instanceof`, NOT a duck-type. `HttpService.handleErrorResponse` throws a real `HttpError` for * every non-2xx response, and `fetch` itself throws a bare `TypeError` when the connection drops - so * the constructor genuinely discriminates. The tempting shortcuts do not: `err?.status` is truthy on any * hand-rolled reject or mocked fetch that happens to carry one, and `err.name === 'HttpError'` is * satisfiable by assignment, since `name` is writable. Both are pinned by their own tests. */ export type OrgFetchFailureKind = 'refused' | 'unreachable'; export const classifyOrgFetchFailure = (error: unknown): OrgFetchFailureKind => error instanceof HttpError ? 'refused' : 'unreachable';