fix(desktop): name the unreachable API on the sign-in screen
What & why
Fixes #7881.
The sign-in screen treats "the API never answered" and "you are not signed in" as the same state. After a GitHub login the deep link returns to the app, the renderer asks NEXT_PUBLIC_API_URL for the session, and when that request dies on the way out (blocked DNS, intercepted TLS, VPN off) the failure only reaches console.warn while the screen shows the sign-in buttons again on every attempt, with nothing saying the API could not be reached.
The session error is now surfaced: useSessionRecovery returns the error from authClient.useSession() (better-auth records the fetch rejection there), a new isNetworkFetchError separates a request that never got an answer (a TypeError, or any error carrying no HTTP status) from one the API answered, and the page names the API it could not reach with a Retry that refetches the session. An HTTP rejection (401, 500) deliberately keeps the quiet behaviour: the API answered, the user is simply signed out.
How I tested it
page.test.tsxrenders the sign-in page with the session mocked to the reported failure. Before the change it asserted that no error was rendered at all (only "Restoring your session" and the provider buttons); it now asserts the message names the API host and that Retry calls the session refetch. Three control cases keep the page quiet: session still in flight, no local token, and an HTTP 401.isNetworkFetchErroris covered in the hook's suite (rejected fetch, error without a status, 401, 500, nothing failed).bun test src/renderer/routes/sign-in— 15 pass / 0 fail.bun run lint,bun run typecheck(42/42 tasks),bun run check:i18n— the new string is translated in all 16 non-English catalogues.- No screenshot: reaching this state needs a stored session token and an API host that fails to resolve, so the render test asserts the exact text instead.
Checklist
- PR title follows conventional commits (
type(scope): subject) -
bun run lintandbun run typecheckpass (CI fails on lint warnings too) - "Allow edits from maintainers" is checked on fork PRs
Summary by cubic
Fixes #7881. The sign-in screen no longer treats "the API never answered" as "not signed in": when a session request dies on the way out (blocked DNS, intercepted TLS, VPN off), the page names the unreachable API host with a Retry button instead of silently returning to the sign-in buttons.
Behavior
useSessionRecoverynow surfaces the session error, and the newisNetworkFetchErrorseparates a request that never got an answer from one the API replied to.- HTTP rejections (401, 500) keep the quiet behavior: the API answered, so the user is simply signed out.
- The API host is parsed only when the message is shown, through a guard that cannot throw, so a malformed
NEXT_PUBLIC_API_URLno longer breaks the dev bypass. - The Retry click catches and logs a failed refetch instead of leaving an unhandled rejection when the API is still down.
- The new message and Retry action are translated across all 16 non-English locales.
Summary by CodeRabbit
- New Features
- During sign-in, network connection failures now show the API host and troubleshooting guidance, with a Retry button to try again.
- The message is available in all supported languages.
- Bug Fixes
- Invalid API addresses are displayed as entered instead of causing an error while the sign-in page loads.