From 05cf664adb1e8efa90079d48b34c9f8e6696a4b7 Mon Sep 17 00:00:00 2001 From: jdalton Date: Fri, 17 Apr 2026 18:10:48 -0400 Subject: [PATCH 1/2] fix(api): include request path in API error messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport of v1.x #1094 to main. When a Socket API request fails, we now always surface the endpoint path in the error message — not just on the non-ok-response branch where we already had it. Specifically: * `queryApiSafeText` catch block (network error) — append `(path: ${path})` * `queryApiSafeText` response-text-read catch — append `(path: ${path})` * `sendApiRequest` catch block (network error) — append `(path: ${path})` * `sendApiRequest` JSON-parse catch — append `(path: ${path})` The `handleApiCall` / `handleApiCallNoSpinner` paths already include `(endpoint: ${description})` so no change there. Closes the coverage gap flagged in the v1.x changelog: "This lacks the request URL, making it difficult to debug which endpoint failed." --- packages/cli/src/utils/socket/api.mts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/utils/socket/api.mts b/packages/cli/src/utils/socket/api.mts index 858a7c6ca..ba6abb379 100644 --- a/packages/cli/src/utils/socket/api.mts +++ b/packages/cli/src/utils/socket/api.mts @@ -456,7 +456,7 @@ export async function queryApiSafeText( return { ok: false, message, - cause: networkDiagnostics, + cause: `${networkDiagnostics} (path: ${path})`, } } @@ -497,7 +497,7 @@ export async function queryApiSafeText( return { ok: false, message: 'API request failed', - cause: 'Unexpected error reading response text', + cause: `Unexpected error reading response text (path: ${path})`, } } } @@ -634,7 +634,7 @@ export async function sendApiRequest( return { ok: false, message, - cause: networkDiagnostics, + cause: `${networkDiagnostics} (path: ${path})`, } } @@ -677,7 +677,7 @@ export async function sendApiRequest( return { ok: false, message: 'API request failed', - cause: 'Unexpected error parsing response JSON', + cause: `Unexpected error parsing response JSON (path: ${path})`, } } } From 933877dd2c58cf9311358320e18c43fb25323b7e Mon Sep 17 00:00:00 2001 From: jdalton Date: Fri, 17 Apr 2026 19:16:02 -0400 Subject: [PATCH 2/2] =?UTF-8?q?test(api):=20assert=20(path:=20=E2=80=A6)?= =?UTF-8?q?=20suffix=20on=20error=20causes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The original #1224 change added `(path: )` to four error causes but the existing tests only asserted loose substrings like "failed" / "parsing" / "response text", so a regression would slip by unnoticed. Adds four targeted assertions inside the existing tests: * queryApiSafeText — network-failure branch * queryApiSafeText — text-read-failure branch * sendApiRequest — network-failure branch * sendApiRequest — JSON-parse-failure branch Each now verifies `result.cause` contains `(path: test/path)`. No new tests added — the existing ones already set up the right mocks for each failure mode, so extending the assertion is the minimum change to actually lock the behavior in. --- packages/cli/test/unit/utils/socket/api.test.mts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/cli/test/unit/utils/socket/api.test.mts b/packages/cli/test/unit/utils/socket/api.test.mts index 297a88a76..7550846f1 100644 --- a/packages/cli/test/unit/utils/socket/api.test.mts +++ b/packages/cli/test/unit/utils/socket/api.test.mts @@ -466,6 +466,9 @@ describe('api utilities', () => { expect(result.ok).toBe(false) if (!result.ok) { expect(result.message).toContain('failed') + // The cause must include the request path so the user can tell + // which endpoint failed when several calls are in flight. + expect(result.cause).toContain('(path: test/path)') } expect(mockFailAndStop).toHaveBeenCalled() }) @@ -490,6 +493,7 @@ describe('api utilities', () => { expect(result.ok).toBe(false) if (!result.ok) { expect(result.cause).toContain('response text') + expect(result.cause).toContain('(path: test/path)') } }) }) @@ -625,6 +629,8 @@ describe('api utilities', () => { expect(result.ok).toBe(false) if (!result.ok) { expect(result.message).toContain('failed') + // Request path must be surfaced in error cause for debuggability. + expect(result.cause).toContain('(path: test/path)') } }) @@ -639,6 +645,7 @@ describe('api utilities', () => { expect(result.ok).toBe(false) if (!result.ok) { expect(result.cause).toContain('parsing') + expect(result.cause).toContain('(path: test/path)') } })