Stop waiting forever on scans that already ended - #144
Conversation
There was a problem hiding this comment.
Automated review risk: 4/5.
The core failure-reporting path breaks when the API returns scan_errors as null. The scan-details fallback URL also mishandles project names containing slashes.
Critical or high-priority changes must be addressed.
Automatic approval was not submitted: automated review found critical or high-priority findings.
There was a problem hiding this comment.
if we check for all scan status why do we need CORGEA_SCAN_TIMEOUT_SECONDS? The issue with this is that we have scans that can take 10 hours or more for big clients. maybe we can set it as 10hours for now and document that clients can override that in the docs
done, it's set to 10 hours, and documentation updates in https://github.com/Corgea/docs/pull/303 |
There was a problem hiding this comment.
Automated review risk: 2/5.
The diff addresses the existing timeout, null deserialization, and URL-encoding comments with targeted tests. No actionable critical, high-priority, or nitpick findings remain in the supplied diff.
No critical or high-priority changes were found.
Automatic approval was not submitted: changes have been requested.
Stop waiting forever on scans that already ended
corgea waitandcorgea scan --waitcould hang until the CI job's owntimeout killed them, and in some cases reported a broken scan as a clean one.
What was wrong
status == "complete",so the API's
incompletestatus fell through to the "still running" branch ofan unbounded loop.
corgea waitwithout--scan-idcompared the listing's status against
"Complete", but the API reportslowercase, so a finished scan was polled again.
failed_reasonor per-scannererrors, so a scan that died had the same output as one that was slow.
"scan_errors": nullfailed to parse.#[serde(default)]covers a missingfield, not an explicit
null, which the API sends for scans with nothing toreport — turning a real failure into a generic read error and losing the reason.
free-form path segment and CI names them
{owner/repo}-{pr}; the unencoded/routed the link into a nested path.What changed
classify_scan_statusgives one terminal-state contract shared by both waitpaths.
incomplete/failed/error/cancelledare terminal and exit1;unknown statuses keep waiting rather than failing a build on a status the
server added later.
failed_reasonplus the reporting scanners. A scan thatcompletes with a scanner's results missing exits
0with a warning, sincethat is the only place coverage loss is visible.
WaitBudgetbounds the wait on a single wall clock shared by every read itmakes, so a stalled request cannot spend the client's 150s timeout on top of
the budget. Default 10 hours, overridable with
CORGEA_SCAN_TIMEOUT_SECONDS.with
CORGEA_BLOCKING_RULES_TIMEOUT_SECONDS, for clients whose scans run long.build_scan_urlreplaces three duplicated URL builders and percent-encodesthe project-name fallback.
check_scan_statusis gone; the loop reads the scan directly, because thelisting omits
failed_reasonandscan_errors.Compatibility
Both new response fields are optional and skipped when empty, so older servers
still deserialize and
corgea ls --jsonoutput is unchanged. Timeouts arebackstops for scans that never report a terminal status — a scan that ends
normally is unaffected, and one that outlives the budget keeps running in the
Corgea cloud.
Tests
tests/cli_scan_wait_terminal_state.rsdrives the real binary against a stubbedscan API and kills it past 30s, so a hang fails a test instead of stalling the
suite: already-failed, fails-mid-poll, degraded-but-complete (via both the first
read and the poll loop), never-finishes, and a stub that accepts the connection
and never answers — covering the budget on both the first read and the loop.
Unit tests cover status classification, timeout parsing and its warning,
WaitBudget, failure and warning formatting with the error-list cap, anddeserialization of missing,
null, and partial fields.Docs:
cli.mdx(5 locales),README.md,skills/corgea/SKILL.md.Linear ticket
Test results
Before fix
After