Skip to content

Preserve HTTP errors from streaming bundle downloads - #4138

Open
henrymercer wants to merge 2 commits into
mainfrom
henrymercer/bundle-download-errors
Open

henrymercer wants to merge 2 commits into
mainfrom
henrymercer/bundle-download-errors

Conversation

@henrymercer

Copy link
Copy Markdown
Contributor

Preserve HTTP status codes when streaming CodeQL bundle downloads fail, so callers can distinguish a missing bundle from other download failures. Rethrow 404s without retrying the same URL through buffered downloading.

Clean up the extraction directory before retrying or rethrowing. Other streaming failures continue to fall back to downloading the bundle before extracting it.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@henrymercer
henrymercer requested a balanced review from Copilot September 10, 2026 18:07
@github-actions github-actions Bot added the size/S Should be easy to review label Sep 10, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

  • Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.

Copilot review overview

🟢 Approval recommended

The behavioral change is well-scoped and validated with targeted tests; only a minor error-message consistency nit was identified.

Review tier: Lite
Findings: 1 Low severity

New issues introduced by this change (1)
Severity Finding
Low severity src/​tools-download.tsresponse.statusCode is treated as potentially undefined (you already fall back to 0 for the…
What changed in this PR

This PR improves error handling for streaming CodeQL bundle downloads by preserving HTTP status codes (notably 404) so callers can distinguish “missing bundle” from transient download failures, while ensuring the extraction directory is cleaned up on failures.

Changes:

  • Throw a typed HTTPError from streaming downloads when the HTTP status is not 200, and rethrow 404s without falling back to buffered download.
  • Always clean the destination extraction directory when the streaming path fails, before retrying/falling back/rethrowing.
  • Add tests covering rethrow-on-404 behavior and fallback-on-5xx behavior, and tighten assertions around cleanup.
File Description
src/​tools-download.ts Preserves HTTP status via HTTPError, cleans extraction dir on streaming failure, and bypasses fallback for 404s.
src/​tools-download.test.ts Adds coverage for 404 rethrow (no retry) and 500 fallback, plus cleanup assertions.
lib/​entry-points.js Generated JS output (excluded by policy; not reviewed).
Files excluded by content exclusion policy (1)
  • lib/entry-points.js

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/tools-download.ts Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@henrymercer
henrymercer requested a balanced review from Copilot September 14, 2026 10:42
@github-actions github-actions Bot added size/M Should be of average difficulty to review and removed size/S Should be easy to review labels Sep 14, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

  • Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.

Copilot review overview

🟢 Approval recommended

The implementation matches the stated behavior and includes focused regression coverage.

Review tier: Balanced
Findings: None

Resolved findings (1)
Files excluded by content exclusion policy (1)
  • lib/entry-points.js

@henrymercer
henrymercer marked this pull request as ready for review September 14, 2026 10:44
@henrymercer
henrymercer requested a review from a team as a code owner September 14, 2026 10:44
@mbg
mbg self-requested a review September 14, 2026 12:59

@mbg mbg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks OK, but with a design question about defaulting to 0 for the status code -- see the detailed comments.

Comment thread src/tools-download.ts
});

if (response.statusCode !== 200) {
const statusCode = response.statusCode ?? 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I have seen the previous review comment from Copilot.)

Why default to 0 here? Based on the review comment from Copilot, it seems that the justification is so that we don't end up with undefined in the HTTPError below, but why even throw a HTTPError at all in that case? Could we throw a non-HTTPError if we don't have a status code instead?

If the HTTPError is needed, e.g. because some upstream handler uses it to distinguish between different scenarios, then it would be worth documenting that here (e.g. "We throw a HTTPError even if we don't have a status code, because ...") or possibly refactoring so that we can throw a different error type here and still get the desired upstream effect.

Comment thread src/tools-download.ts
Comment on lines +207 to +211
let message = `Failed to download CodeQL bundle from ${codeqlURL}.`;
if (statusCode !== 0) {
message += ` HTTP status code: ${statusCode}.`;
}
throw new HTTPError(message, statusCode);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: The message is only used once, so it might be nicer (especially if we throw a different kind of error in the absence of a statusCode) to have e.g.

Suggested change
let message = `Failed to download CodeQL bundle from ${codeqlURL}.`;
if (statusCode !== 0) {
message += ` HTTP status code: ${statusCode}.`;
}
throw new HTTPError(message, statusCode);
const baseMessage = `Failed to download CodeQL bundle from ${codeqlURL}.`;
if (statusCode !== 0) {
throw new HTTPError(`${baseMessage} HTTP status code: ${statusCode}.`;
}
throw new SomeOtherError(baseMessage);

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

Labels

size/M Should be of average difficulty to review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants