diff --git a/src/consume.ts b/src/consume.ts index a365656bb..35a23041b 100644 --- a/src/consume.ts +++ b/src/consume.ts @@ -18,7 +18,7 @@ import { registerCommandWithLogging } from "./commands"; import { LOCAL_CONNECTION_ID } from "./constants"; import { getExtensionContext } from "./context/extension"; import { showJsonPreview } from "./documentProviders/message"; -import { logError } from "./errors"; +import { extractResponseBody, logError } from "./errors"; import type { ResourceLoader } from "./loaders"; import { CCloudResourceLoader, DirectResourceLoader, LocalResourceLoader } from "./loaders"; import { Logger } from "./logging"; @@ -504,7 +504,9 @@ function messageViewerStartPollingCommand( /* In case of network issue, the current assumption is that the user is going to see auth related error alerts. Logging and error displays is WIP. */ if (error instanceof ResponseError) { - const payload = await error.response.json(); + // parse defensively: on an empty body a raw `.json()` throws `Unexpected end of JSON + // input`, which would abort this catch block before the stream pauses or the user is told. + const payload = await extractResponseBody(error); // FIXME: this response error coming from the middleware that has to be present to avoid openapi error about missing middlewares if (!payload?.aborted) { const status = error.response.status; diff --git a/src/errors.test.ts b/src/errors.test.ts index a6ba83230..13f0a6d25 100644 --- a/src/errors.test.ts +++ b/src/errors.test.ts @@ -206,6 +206,16 @@ describe("errors.ts extractResponseBody()", () => { assert.strictEqual(body, textResponse); }); + it("should return an empty string for an empty response body", async () => { + // an empty body makes `JSON.parse("")` throw `Unexpected end of JSON input`; the helper must + // swallow that and fall back to the (empty) text body rather than propagating the SyntaxError. + const error = createResponseError(500, "Internal Server Error", ""); + + const body = await extractResponseBody(error); + + assert.strictEqual(body, ""); + }); + it("should throw if the error is not a ResponseError", async () => { const error = new Error("test"); await assert.rejects(