fix: show OSV retry hints for 429 and 5xx responses#428
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds more granular OSV error classification (rate-limit vs server errors) and prints tailored CLI hints to guide users toward retries or offline scans.
Changes:
- Introduces
isRateLimitError/isServerErrorutilities and associated hint helpers. - Updates CLI error handling to print distinct hints for OSV 429 and 5xx responses.
- Adds unit and integration tests covering the new error paths.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| tests/network.test.ts | Adds unit tests for new network error classifiers. |
| tests/cli-integration.test.ts | Adds integration tests asserting new CLI hints for OSV 429/5xx. |
| src/utils/network.ts | Implements new error classifiers and hint text; refines blocked-error detection. |
| src/index.ts | Prints new hints based on rate-limit/server error classification. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (isRateLimitError(message) || isServerError(message)) { | ||
| return false; | ||
| } |
| if (isRateLimitError(message) || isServerError(message)) { | ||
| return false; | ||
| } | ||
|
|
||
| const finalCause = finalErrorCause(message); |
sonukapoor
left a comment
There was a problem hiding this comment.
Nice addition - 429 and 5xx now get targeted hints instead of falling through to the generic blocked-network message. The detection logic and test coverage are solid. One DRY issue to fix before merge.
| export function serverAdvisoryRequestHint(): string[] { | ||
| return [ | ||
| "Hint: OSV API may be temporarily unavailable. Wait a moment and retry, or scan offline:", | ||
| " cve-lite . --offline", |
There was a problem hiding this comment.
Lines 29-30 (in rateLimitAdvisoryRequestHint) and 37-38 here are identical. If the offline hint text ever changes, both functions need to be updated in sync. Could you extract those two lines to a shared constant and spread it in?
const OFFLINE_FALLBACK_LINES = [
" cve-lite . --offline",
" (requires a local advisory DB - run `cve-lite advisories sync` to build one)",
];
export function rateLimitAdvisoryRequestHint(): string[] {
return ["Hint: OSV API rate limit reached. Wait a moment and retry, or scan offline:", ...OFFLINE_FALLBACK_LINES];
}
export function serverAdvisoryRequestHint(): string[] {
return ["Hint: OSV API may be temporarily unavailable. Wait a moment and retry, or scan offline:", ...OFFLINE_FALLBACK_LINES];
}| "OSV vuln fetch failed for OSV-404 via https://api.osv.dev: OSV vuln fetch failed for OSV-404: 404 Not Found", | ||
| ), | ||
| ).toBe(false); | ||
| }); |
There was a problem hiding this comment.
Small symmetry note: isRateLimitError has a test for non-OSV 429 (line 91) returning false, but isServerError doesn't have the equivalent. Would be good to add:
it("returns false for non-OSV 5xx responses", () => {
expect(isServerError("API failed: 500 Internal Server Error")).toBe(false);
});032cead to
8bb895e
Compare
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
8bb895e to
40a116a
Compare
sonukapoor
left a comment
There was a problem hiding this comment.
All feedback addressed. OFFLINE_FALLBACK_LINES extracted cleanly, the non-OSV 5xx test is in, and the extra refactoring is a nice touch - pulling isRateLimitCause and isServerCause out as private helpers means isLikelyBlockedAdvisoryRequestError shares the same regex logic without duplicating the cause extraction, and the fallback regex is now correctly trimmed to just the auth/proxy/legal codes. Good work.
Closes #403
Summary
Before / after
Before, OSV 429 and 503 responses only surfaced the raw HTTP status or generic network guidance.
After, 429 responses tell users to wait and retry or scan with
--offline. 5xx responses explain that OSV may be temporarily unavailable and give the same offline fallback.Validation