feat: add reauthOnFailure option to FamisClient#103
Merged
Conversation
…lback Adds an opt-in `reauthOnFailure` flag to `FamisClient.withLoginCredential`. When enabled, the client reactively handles 401 responses: it first attempts a refresh-token swap (preferred), and if that fails, performs a full re-login using the stored username/password before retrying the original request once. This makes explicit a behavior the legacy connector relied on implicitly. When the flag is omitted (default `false`), behavior is unchanged: 401s propagate. Architectural notes: - Reactive 401 path implemented as a NEW response interceptor that is only attached when `reauthOnFailure` is true, leaving the default code path byte-for-byte identical to before. - Loop prevention via a `_reauthRetry` marker on the request config — a single request is never retried more than once. - Stored credentials are populated only when the flag is on. - Reuses `FamisClient.login` and `FamisClient.refreshAuthCredential`; no new HTTP plumbing. Tests added in tests/reauth-on-failure.test.ts cover: rescue-on-401, no-infinite-loop on persistent 401, and unchanged default behavior. Refs: docs/superpowers/plans/2026-05-05-facility360-rebuild.md Task 0.5 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
320eedc to
1913321
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an opt-in
reauthOnFailureflag toFamisClient.withLoginCredential. When enabled, the client reactively handles 401 responses — it first tries the refresh-token swap, and if that also fails, falls back to a full re-login with the stored username/password and retries the original request once.This makes explicit a behavior the legacy connector previously relied on implicitly. When the flag is omitted (default
false), behavior is unchanged: 401s propagate asApiErrorexactly as before.Why
The connector platform overhaul wants the silent re-login behavior of the old SDK to be opt-in and explicit, rather than always-on. New connectors should be able to choose: refresh-token-only (default) or full-re-login fallback (opt-in).
Refs:
docs/superpowers/plans/2026-05-05-facility360-rebuild.mdTask 0.5.Architectural choices
reauthOnFailureis true. The default code path is byte-for-byte identical to before._reauthRetrymarker on the request config — a single request is never retried more than once.this.reauthCredentialsstaysundefinedotherwise).FamisClient.loginandFamisClient.refreshAuthCredential— no new HTTP plumbing.validateStatus: () => true, so 401 responses RESOLVE rather than reject. The new interceptor lives in the success arm and inspectsresponse.status === 401.Test plan
tests/reauth-on-failure.test.tscovers three behaviors:reauthOnFailure: truerescues a hard 401 (refresh fails, full login succeeds), token swapped, retried exactly once.reauthOnFailure: truedoes NOT loop on persistent 401 — retries exactly once and surfaces the failure.reauthOnFailure: false(default) propagates the 401 unchanged; refresh and login are never invoked reactively.yarn test— full suite passes (6 tests across 2 suites).yarn build— clean.Notes / scope
withLoginCredentialonly.withAccessTokenis unaffected: it has no username/password to fall back on, so re-login fundamentally cannot apply there. If callers usingwithAccessTokenlater need a similar hook, they'd need to supply a refresh callback, which is out of scope here.🤖 Generated with Claude Code