Skip to content

fix(setup): report a key-check timeout as REQUEST_TIMEOUT instead of "API key rejected" - #647

Open
Andy00L wants to merge 1 commit into
TestSprite:mainfrom
Andy00L:fix/setup-timeout-not-rejected
Open

Andy00L wants to merge 1 commit into
TestSprite:mainfrom
Andy00L:fix/setup-timeout-not-rejected

Conversation

@Andy00L

@Andy00L Andy00L commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

What does this PR do?

When the GET /me key check in setup timed out on the client side, setup told the user their API key was rejected and exited 3, the auth family. The natural reaction is to rotate a key that works. The same stall on any other command gives REQUEST_TIMEOUT and exit 7. setup now reports the timeout as what it is, with the same typed error, and still writes nothing.

  • The catch. runConfigure rethrows RequestTimeoutError unchanged, next to the InterruptError rethrow, so it keeps its REQUEST_TIMEOUT code, exit 7, nextAction and cli_… request id. Before, it fell into the non-ApiError branch, which wrapped it in an exit-3 CLIError ("API key rejected … did you mean to set TESTSPRITE_API_URL?").
  • The stderr line. It now reads API key check against <url> timed out, profile NOT updated: <message> instead of "API key rejected". Nothing is written to the credentials file, as before.
  • Unchanged. A 401 or any other typed ApiError from /me still exits 3 with its envelope, and any other unexpected throw keeps the exit-3 wrapper.

Related issue

Closes #614

Season 4 CLI Improvement Bonus

  • I'm entering this PR for the Season 4 CLI Improvement Bonus

Discord username: interferon0

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that changes existing behavior)
  • Documentation only
  • Build / CI / chore

Checklist

  • PR targets the main branch.
  • Commits follow Conventional Commits
    (feat(...), fix(...), docs(...), …).
  • npm run lint and npm run format:check pass.
  • npm run typecheck passes.
  • npm test passes and coverage stays at or above the 80% gate.
  • New behavior is covered by unit tests (mock-based; no network or
    credentials required).
  • No secrets, API keys, internal endpoints, or personal data are included.
  • User-facing changes are reflected in README.md / DOCUMENTATION.md where
    relevant.

Notes for reviewers

  • Tests, in init.test.ts at the setup --from-env level:

    • A fetch that never answers (it only rejects on abort) with requestTimeoutMs: 20: setup throws RequestTimeoutError with REQUEST_TIMEOUT, exit 7 and a cli_ request id, writes no credentials, and stderr says "timed out, profile NOT updated", never "API key rejected". On current main (a18d37c) this test fails with expected CLIError: API key rejected by https://api… to be an instance of RequestTimeoutError.
    • A 401 from /me still exits 3 with AUTH_INVALID, its nextAction and request id. This one is a control and passes before and after.
    • The existing uses requestTimeoutMs for the pre-write key validation ping test in auth.test.ts keeps passing, since RequestTimeoutError is a CLIError.
  • End to end with the built CLI against a local server that accepts the connection and never answers, --request-timeout 2 setup --from-env --no-agent --output json now prints the same envelope as project list against that server, and no credentials file is written:

    API key check against http://127.0.0.1:41491 timed out, profile NOT updated: Request timed out after 2s (client-side). Use --request-timeout <seconds> or TESTSPRITE_REQUEST_TIMEOUT_MS to extend the deadline.
    { "error": { "code": "REQUEST_TIMEOUT", ..., "requestId": "cli_3731238d-...", "details": { "timeoutMs": 2000 } } }
    exit=7
    

    On v0.15.0 the same run printed "code": "CLI_ERROR", "requestId": "local" and exited 3.

  • fix(setup): apply TESTSPRITE_REQUEST_TIMEOUT_MS to the pre-write key verification ping #626 (for [Hackathon] setup key verification ignores TESTSPRITE_REQUEST_TIMEOUT_MS #470) changes the import block and the HttpClient options a few lines above this catch. Whichever lands second needs a one-line rebase on the errors.js import.

  • Local run: npm run lint (0 errors; the warnings are existing unused eslint-disable directives), npm run format:check, npm run typecheck, npm test (122 files, 4800 passed, 2 skipped), npm run test:e2e (10 files, 110 passed, 1 skipped) and npm run test:coverage (statements 90.1%, branches 85.1%, lines 92.3%).

Summary by CodeRabbit

  • Bug Fixes
    • Configuration requests that time out now show a timeout error instead of an authentication error, and the profile remains unchanged.
    • Rejected API keys continue to show an authentication error.

…"API key rejected"

runConfigure wrapped every non-ApiError from the GET /me key check in an
exit-3 "API key rejected" CLIError. RequestTimeoutError extends CLIError,
not ApiError, so a stalled check told the user their key was rejected and
dropped the REQUEST_TIMEOUT code and request id. Rethrow it unchanged
(exit 7) and say on stderr that the check timed out; the profile is still
not written.

Closes TestSprite#614
@github-actions

Copy link
Copy Markdown

🏆 Season 4 CLI Improvement Bonus: entry recorded. Thanks, @Andy00L!

To be counted, this PR needs the following by Oct 29, 11:59 PM PT:

  • ✅ A linked issue assigned to you.
  • ✅ Out of draft.
  • ✅ A Discord username in the description.

Rewards go to merged PRs judged a genuine improvement, and up to three bonus-eligible PRs count per person. Untick the box to withdraw the entry. This comment refreshes when you edit the PR. Full rules.

@github-actions github-actions Bot added the s4-cli-bonus Entered for the Season 4 CLI Improvement Bonus label Oct 22, 2026
@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
📥 Commits

Reviewing files that changed from the base of the PR and between a18d37c and 126a456.

📒 Files selected for processing: 2
  • src/commands/auth.ts
  • src/commands/init.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Walkthrough

Key verification now preserves client-side request timeout errors instead of treating them as rejected API keys. Tests cover timeout and unauthorized responses, including their error details, exit codes, request IDs, and credential-saving behavior.

Changes

Setup key verification

Layer / File(s) Summary
Preserve timeout errors during key verification
src/commands/auth.ts, src/commands/init.test.ts
runConfigure reports that the profile was not updated and rethrows RequestTimeoutError unchanged. Tests verify timeout and 401 error details, exit codes, request IDs, and that a timeout does not save credentials.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related issues

  • Issue 397 covers a similar timeout classification problem in environment preflight, not setup key verification.
  • Issue 470 concerns the timeout deadline source for setup’s GET /me request, rather than timeout classification.
Merge Risk: ⚪ Minimal · up to 126a4

No actionable merge-blocking issue is identified; the change is ready for normal checks.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: reporting setup key-check timeouts as REQUEST_TIMEOUT instead of an API key rejection.
Linked Issues check Passed The PR satisfies #614. In src/commands/auth.ts, runConfigure rethrows RequestTimeoutError unchanged after writing the timeout-specific profile NOT updated message. This preserves `REQUEST_TIME…
Out of Scope Changes check Passed The changes stay within #614. The production change only separates client-side timeout handling from key-rejection handling in setup. The added tests cover the requested timeout behavior and protect…
Full details: Linked Issues check

Explanation

The PR satisfies #614. In src/commands/auth.ts, runConfigure rethrows RequestTimeoutError unchanged after writing the timeout-specific profile NOT updated message. This preserves REQUEST_TIMEOUT, exit code 7, timeout details, and the request ID. The existing ApiError path remains unchanged for 401 responses and keeps exit code 3 with the typed envelope. The new init.test.ts tests verify the timeout behavior, request ID, no saved profile, stderr text, and the 401 control case.

Full details: Out of Scope Changes check

Explanation

The changes stay within #614. The production change only separates client-side timeout handling from key-rejection handling in setup. The added tests cover the requested timeout behavior and protect the required 401 behavior. No unrelated product behavior or files are changed.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

s4-cli-bonus Entered for the Season 4 CLI Improvement Bonus

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Hackathon] fix(setup): a timeout while verifying the key is reported as "API key rejected", exit 3, instead of REQUEST_TIMEOUT exit 7

1 participant