fix(auth): degrade adapter import failures to per-site error rows#1915
Open
Chen17-sq wants to merge 1 commit into
Open
fix(auth): degrade adapter import failures to per-site error rows#1915Chen17-sq wants to merge 1 commit into
Chen17-sq wants to merge 1 commit into
Conversation
loadLazyCommand() awaits import() of lazy/manifest adapters but ran outside the per-site try/catch in runQuick/runFull/runRefresh. An adapter that throws at import time rejected its worker promise, which rejected the Promise.all in mapConcurrent and crashed the entire auth status / auth refresh aggregate. Move loadLazyCommand() and the dependent command-shaping (quickCheckCommand / withTimeoutArg / refreshCommand, plus the not-implemented/unsupported early-returns) inside the existing per-site try so import/probe failures degrade to an error row via rowForError / refreshRowForError, matching the module's existing failure-to-row design. The runRefresh throttle/skip check stays before the try; the catch path still records last_attempt_at / last_status so state stays consistent.
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.
Problem
opencli auth statusandopencli auth refreshaggregate results across every registeredwhoamiadapter, concurrently, viamapConcurrent(whichawait Promise.alls its workers). The whole subsystem is designed to degrade every per-site failure into a result row (rowForError/refreshRowForError) — the "network down" test atauth.test.tsproves this is the intended contract.But one failure mode was not protected: a lazy/manifest-loaded adapter that throws at import/probe time. Such an adapter rejects its worker promise, which rejects the
Promise.allinmapConcurrent, which crashes the entireauth status/auth refreshrun — so a single malformed adapter takes down the status of every other site.Root cause
In
src/commands/auth.ts,loadLazyCommand(cmd)performsawait import(pathToFileURL(internal._modulePath).href)for lazy adapters (registered with_lazy: true/_modulePathatdiscovery.ts:139-140). In all three workers this call — plus the dependent command-shaping — sat outside the existing per-sitetry/catch:runQuick—auth.ts:273(loadLazyCommand+quickCheckCommand) was before thetryat line 286.runFull—auth.ts:314(loadLazyCommand+withTimeoutArg) was before thetryat line 316.runRefresh—auth.ts:355(loadLazyCommand+refreshCommand+ the!refreshCmdunsupported branch) was before thetryat line 368.The
catchblocks already map failures to error rows, but they could never see an import-time throw because it happened before thetrywas entered.Fix
Move
loadLazyCommand()and its dependent command-shaping (quickCheckCommand/withTimeoutArg/refreshCommand), along with the not-implemented (!quickCmd) and unsupported (!refreshCmd) early-returns, inside the existing per-sitetryin each of the three workers. No signature changes, no new helpers — 3 hunks.{ status: 'error', logged_in: '', error: <message> }(status) / astatus: 'error'row (refresh), exactly like any other adapter failure, and the aggregate resolves with rows for all other sites.runRefresh: the throttle/skip check (lines 343-352) intentionally stays before thetryso it is unaffected; thecatchcontinues to recordlast_attempt_at/last_status: 'error'so refresh state stays consistent andsaveAuthRefreshStatestill runs.Tests
Added 3 tests to
src/commands/auth.test.ts. A helper registers a lazywhoamiadapter (_lazy: true+_modulePathpointing at a temp.mjswhose top-level body doesthrow new Error('boom')), mirroringdiscovery.tsmanifest registration:collectAuthStatuswith one healthy quick-check site + one import-throwing lazy site — asserts it resolves (does not reject) and returns both rows, the bad site asstatus: 'error'/logged_in: ''/ error containingboom, the good site unaffected.collectAuthRefresh— same mix; the bad site yields astatus: 'error'row, the good site is still touched, and the aggregate does not throw.saveAuthRefreshStateran): the good site recordslast_status: 'touched', the failing site recordslast_attempt_at/last_status: 'error'with nolast_touched_at.Verification:
npx tsc --noEmitclean;npx vitest run src/commands/auth.test.ts-> 13 passed. Confirmed the tests fail on the unpatched source (unhandledboomrejection) and pass with the fix.Scope
Surgical hardening faithful to the module's existing failure-to-row design; only
auth.tsworkers + co-located tests. Edge-case (requires a malformed/throwing adapter module), but currently uncovered, so the per-site error contract silently didn't hold for import failures. No open issue/PR touches this file (only #1879/#1881, both merged).