Skip to content

refactor: drop try/catch around client calls that cannot throw#98

Merged
Bccorb merged 1 commit into
mainfrom
refactor/remove-dead-catches
Jul 20, 2026
Merged

refactor: drop try/catch around client calls that cannot throw#98
Bccorb merged 1 commit into
mainfrom
refactor/remove-dead-catches

Conversation

@Bccorb

@Bccorb Bccorb commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

What

Remove the try/catch blocks that guarded client calls which can no longer throw, and document the few that are kept on purpose.

Closes #89.

Removed

Six unreachable handlers, all wrapping nothing but client calls whose failures already arrive through error:

  • AuthProvider: the catch in logout and logoutAllSessions
  • Login: register, sendMagicLink, sendPhoneOtp, sendEmailOtp
  • PhoneRegistration: the inner verifyPhoneOTP handler
  • VerifyMagicLink: the verify handler

Kept, with a comment saying why

Not every catch here was dead, so these stay and now explain themselves rather than implying the client throws:

  • Login, PhoneRegistration, and EmailRegistration submit handlers, as backstops for genuinely unexpected errors
  • the MagicLinkSent poll, because a rejection inside a timer has no caller to surface it

Untouched elsewhere, because they guard code that really does throw: startAuthentication and startRegistration (a cancelled prompt), response.json() and the fetch promise in the result layer, localStorage in private mode, Intl in phoneInput, and startOAuthLogin in OAuthProviderButtons, which is a provider helper and therefore throws by design.

logout keeps its guarantee

logout and logoutAllSessions became try/finally rather than losing the block entirely. The catch was dead, but the finally is load-bearing: local auth state must be cleared even when the server call fails, or the UI keeps presenting a signed-in user whose session is gone. There is a comment on both, and the test added in #96 covers it.

This exposed two tests that were passing for the wrong reason

logs out if token validation fails (bad response) and logs out if token validation throws both mocked only the /users/me call. validateToken then calls logout(), whose request was never mocked and resolved undefined, which made requestResult throw a TypeError while reading response.ok. The old catch in logout swallowed it, so the tests passed while asserting less than they appeared to.

With the catch gone the TypeError surfaced, so both mocks now provide the logout response as well. The assertions are unchanged and now actually exercise the path they describe.

Worth noting the underlying detail: requestResult assumes the request promise resolves to a Response. That only breaks under a bad mock or a broken fetch shim, so I did not add speculative defence, but it is the reason those tests failed the moment the catch went away.

Checks

  • npm run typecheck, npm run lint, npm run format:check clean
  • Full suite: 221 passed
  • Coverage improved as dead branches disappeared: Login.tsx 73.3% to 76.9% statements, PhoneRegistration.tsx 89.4% to 91.5%, VerifyMagicLink.tsx 93.9% to 95.7%, repo overall 88.9% to 89.7%
  • No changeset: no behavior change for adopters

@Bccorb
Bccorb merged commit e15ae8c into main Jul 20, 2026
2 of 3 checks passed
@Bccorb
Bccorb deleted the refactor/remove-dead-catches branch July 20, 2026 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove try/catch blocks that guard client calls which no longer throw

1 participant