diff --git a/packages/core/src/apierror/apierror.ts b/packages/core/src/apierror/apierror.ts index eff5ca52..fcb585dd 100644 --- a/packages/core/src/apierror/apierror.ts +++ b/packages/core/src/apierror/apierror.ts @@ -141,17 +141,20 @@ export class ApiError extends Error { }); } - // Decode the body to a string for JSON parsing. + // Decode the body once; it doubles as the JSON source and as a readable + // fallback message for non-JSON or non-conforming bodies. + const decoded = new TextDecoder().decode(body); + let parsed: unknown; try { - parsed = JSON.parse(new TextDecoder().decode(body)); + parsed = JSON.parse(decoded); } catch (e: unknown) { - // The JSON error is simply swallowed, this typically happens when the - // error does not come directly from a Databricks API. A typical example - // is when the error is returned by a proxy. + // The body is not JSON; this typically happens when the error does not + // come directly from a Databricks API (e.g. a proxy). Surface the decoded + // body as the message so the failure is debuggable instead of empty. return new ApiError({ code: Code.UNKNOWN, - message: '', + message: decoded, details: emptyDetails, httpStatusCode: statusCode, httpHeader: header, @@ -162,9 +165,11 @@ export class ApiError extends Error { const result = errorResponseSchema.safeParse(parsed); if (!result.success) { + // The body parsed as JSON but does not match the error schema. Surface + // the decoded body as the message so the failure is debuggable. return new ApiError({ code: Code.UNKNOWN, - message: '', + message: decoded, details: emptyDetails, httpStatusCode: statusCode, httpHeader: header, diff --git a/packages/core/tests/apierror/apierror.test.ts b/packages/core/tests/apierror/apierror.test.ts index 4802fcdc..063bcfca 100644 --- a/packages/core/tests/apierror/apierror.test.ts +++ b/packages/core/tests/apierror/apierror.test.ts @@ -160,22 +160,22 @@ describe('fromHttpError', () => { }), }, { - desc: 'HTML body', + desc: 'HTML body decoded into message', statusCode: 502, body: encode('Bad Gateway'), want: new ApiError({ code: Code.UNKNOWN, - message: '', + message: 'Bad Gateway', details: emptyDetails, }), }, { - desc: 'malformed JSON', + desc: 'malformed JSON decoded into message', statusCode: 400, body: encode('{not valid json'), want: new ApiError({ code: Code.UNKNOWN, - message: '', + message: '{not valid json', details: emptyDetails, }), },