Context
packages/loopover-miner/lib/oauth-device-flow.js's two GitHub-facing fetches — requestDeviceCode (line 39) and pollForAccessToken's per-attempt fetch (line 78) — call fetchFn with no AbortSignal.timeout/timeout option, unlike every other GitHub-facing fetch in this package (e.g. github-token-resolution.js:94's signal: AbortSignal.timeout(GITHUB_TOKEN_FETCH_TIMEOUT_MS), and everything routed through http-retry.js's fetchOnce) under the documented #miner-github-read-timeouts pattern: "a stalled connection can't hang ... forever."
pollForAccessToken's own deadline check (line 76) only fires between polling attempts, so a single stalled connection mid-fetch can hang indefinitely rather than being caught by the deadline. This directly undermines init-wizard.js:70-87's documented "never a hard dependency ... automatic fallback on any device-flow failure" — a hang never reaches the catch that's supposed to trigger the pasted-token fallback, since the fetch itself never resolves or rejects.
Requirements
- Add a request timeout to
requestDeviceCode's fetch, using the same AbortSignal.timeout(...) pattern as github-token-resolution.js:94.
- Add the same timeout to
pollForAccessToken's per-attempt fetch.
- Reuse (or define alongside, if a distinct constant is warranted) the existing timeout-duration constant convention rather than a new magic number.
- Ensure a fetch timeout during polling is treated as a per-attempt failure that can still retry (respecting the existing
deadline), not as an unhandled rejection that crashes the flow.
Deliverables
Test Coverage Requirements
99%+ Codecov patch coverage on every changed line and branch, plus the regression test above.
Expected Outcome
A stalled GitHub connection during device-flow auth can no longer hang indefinitely — it times out and correctly reaches init-wizard.js's documented pasted-token fallback, matching every other GitHub-facing fetch in this package.
Links & Resources
packages/loopover-miner/lib/github-token-resolution.js:94 — the AbortSignal.timeout precedent. packages/loopover-miner/lib/http-retry.js — the shared retry/timeout pattern used elsewhere. packages/loopover-miner/lib/init-wizard.js:70-87 — the fallback behavior this issue protects.
Context
packages/loopover-miner/lib/oauth-device-flow.js's two GitHub-facing fetches —requestDeviceCode(line 39) andpollForAccessToken's per-attempt fetch (line 78) — callfetchFnwith noAbortSignal.timeout/timeout option, unlike every other GitHub-facing fetch in this package (e.g.github-token-resolution.js:94'ssignal: AbortSignal.timeout(GITHUB_TOKEN_FETCH_TIMEOUT_MS), and everything routed throughhttp-retry.js'sfetchOnce) under the documented#miner-github-read-timeoutspattern: "a stalled connection can't hang ... forever."pollForAccessToken's owndeadlinecheck (line 76) only fires between polling attempts, so a single stalled connection mid-fetch can hang indefinitely rather than being caught by the deadline. This directly underminesinit-wizard.js:70-87's documented "never a hard dependency ... automatic fallback on any device-flow failure" — a hang never reaches thecatchthat's supposed to trigger the pasted-token fallback, since the fetch itself never resolves or rejects.Requirements
requestDeviceCode's fetch, using the sameAbortSignal.timeout(...)pattern asgithub-token-resolution.js:94.pollForAccessToken's per-attempt fetch.deadline), not as an unhandled rejection that crashes the flow.Deliverables
requestDeviceCode's fetch has a request timeoutpollForAccessToken's fetch has a request timeoutTest Coverage Requirements
99%+ Codecov patch coverage on every changed line and branch, plus the regression test above.
Expected Outcome
A stalled GitHub connection during device-flow auth can no longer hang indefinitely — it times out and correctly reaches
init-wizard.js's documented pasted-token fallback, matching every other GitHub-facing fetch in this package.Links & Resources
packages/loopover-miner/lib/github-token-resolution.js:94— theAbortSignal.timeoutprecedent.packages/loopover-miner/lib/http-retry.js— the shared retry/timeout pattern used elsewhere.packages/loopover-miner/lib/init-wizard.js:70-87— the fallback behavior this issue protects.