fix(ext/sw): consistent error detail across all 6 putBlob throw paths

The two GET steps (get-ref, get-commit) used resp.statusText, which is
often empty on HTTP/2. Now they read resp.text() like the other 4 throw
paths so every error message includes GitHub's response body for
debugging.

Plus a test assertion for calls[2] in the Git Data API path so a
transposition of GET ref / GET commit would be caught.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
adlee-was-taken
2026-04-25 15:42:19 -04:00
parent 63fcfae72c
commit dc660c4ce8
2 changed files with 5 additions and 2 deletions

View File

@@ -55,6 +55,7 @@ describe('GitHubHost.putBlob', () => {
expect(fetchMock).toHaveBeenCalledTimes(6); expect(fetchMock).toHaveBeenCalledTimes(6);
expect(fetchMock.mock.calls[0][0]).toContain('/git/blobs'); expect(fetchMock.mock.calls[0][0]).toContain('/git/blobs');
expect(fetchMock.mock.calls[1][0]).toContain('/git/refs/heads/'); expect(fetchMock.mock.calls[1][0]).toContain('/git/refs/heads/');
expect(fetchMock.mock.calls[2][0]).toContain('/git/commits/');
expect(fetchMock.mock.calls[3][0]).toContain('/git/trees'); expect(fetchMock.mock.calls[3][0]).toContain('/git/trees');
expect(fetchMock.mock.calls[4][0]).toContain('/git/commits'); expect(fetchMock.mock.calls[4][0]).toContain('/git/commits');
expect(fetchMock.mock.calls[5][1]?.method).toBe('PATCH'); expect(fetchMock.mock.calls[5][1]?.method).toBe('PATCH');

View File

@@ -135,14 +135,16 @@ export class GitHubHost implements GitHost {
// 2. Get current ref (branch tip commit SHA). // 2. Get current ref (branch tip commit SHA).
const refResp = await fetch(`${this.gitApiBase}/refs/heads/${this.branch}`, { headers: this.headers }); const refResp = await fetch(`${this.gitApiBase}/refs/heads/${this.branch}`, { headers: this.headers });
if (!refResp.ok) { if (!refResp.ok) {
throw new Error(`GitHub putBlob get-ref ${this.branch}: ${refResp.status} ${refResp.statusText}`); const text = await refResp.text();
throw new Error(`GitHub putBlob get-ref ${this.branch}: ${refResp.status} ${text}`);
} }
const { object: { sha: commitSha } } = await refResp.json() as { object: { sha: string } }; const { object: { sha: commitSha } } = await refResp.json() as { object: { sha: string } };
// 3. Get current commit's tree SHA. // 3. Get current commit's tree SHA.
const commitResp = await fetch(`${this.gitApiBase}/commits/${commitSha}`, { headers: this.headers }); const commitResp = await fetch(`${this.gitApiBase}/commits/${commitSha}`, { headers: this.headers });
if (!commitResp.ok) { if (!commitResp.ok) {
throw new Error(`GitHub putBlob get-commit ${commitSha}: ${commitResp.status} ${commitResp.statusText}`); const text = await commitResp.text();
throw new Error(`GitHub putBlob get-commit ${commitSha}: ${commitResp.status} ${text}`);
} }
const { tree: { sha: baseTreeSha } } = await commitResp.json() as { tree: { sha: string } }; const { tree: { sha: baseTreeSha } } = await commitResp.json() as { tree: { sha: string } };