From d98ed127dab7a79585d70512b9210bf9dd2c6e9d Mon Sep 17 00:00:00 2001 From: Nikos Polykandriotis Date: Thu, 21 Dec 2023 17:18:08 +0200 Subject: [PATCH] fix(backend): Add missing details to backend API errors This was caused by API errors beeing parsed twice. Once in the response error handling and again when initializing a new ClerkAPIResponseError. --- .changeset/lucky-snails-help.md | 5 +++++ packages/backend/src/api/factory.test.ts | 12 +++++++++++- packages/backend/src/api/request.ts | 18 +++++++++++------- 3 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 .changeset/lucky-snails-help.md diff --git a/.changeset/lucky-snails-help.md b/.changeset/lucky-snails-help.md new file mode 100644 index 00000000000..1b8269f8d59 --- /dev/null +++ b/.changeset/lucky-snails-help.md @@ -0,0 +1,5 @@ +--- +'@clerk/backend': patch +--- + +Fixed a bug where backend API responses where missing error details. This was caused by parsing the errors twice once in the response error handling code and again when initializing the ClerkAPIResponseError. diff --git a/packages/backend/src/api/factory.test.ts b/packages/backend/src/api/factory.test.ts index a7d373569e6..2d403c26aba 100644 --- a/packages/backend/src/api/factory.test.ts +++ b/packages/backend/src/api/factory.test.ts @@ -150,7 +150,14 @@ export default (QUnit: QUnit) => { }); test('executes a failed backend API request and parses the error response', async assert => { - const mockErrorPayload = { code: 'whatever_error', message: 'whatever error', meta: {} }; + const mockErrorPayload = { + code: 'whatever_error', + message: 'whatever error', + long_message: 'some long message', + meta: { + param_name: 'whatever_param', + }, + }; const traceId = 'trace_id_123'; fakeFetch = sinon.stub(runtime, 'fetch'); fakeFetch.onCall(0).returns(jsonNotOk({ errors: [mockErrorPayload], clerk_trace_id: traceId })); @@ -162,6 +169,9 @@ export default (QUnit: QUnit) => { assert.equal(e.clerkError, true); assert.equal(e.status, 422); assert.equal(e.errors[0].code, 'whatever_error'); + assert.equal(e.errors[0].message, 'whatever error'); + assert.equal(e.errors[0].longMessage, 'some long message'); + assert.equal(e.errors[0].meta.paramName, 'whatever_param'); } assert.ok( diff --git a/packages/backend/src/api/request.ts b/packages/backend/src/api/request.ts index 0cadfd69a23..d0b44f08bae 100644 --- a/packages/backend/src/api/request.ts +++ b/packages/backend/src/api/request.ts @@ -51,18 +51,22 @@ type LegacyRequestFunction = (requestOptions: ClerkBackendApiRequestOptions) * TODO: Simply remove this wrapper and the ClerkAPIResponseError before the v5 release. */ const withLegacyReturn = - (cb: any): LegacyRequestFunction => + (cb: (...args: any) => Promise>): LegacyRequestFunction => async (...args) => { - // @ts-ignore - const { data, errors, status, statusText, clerkTraceId } = await cb(...args); - if (errors === null) { - return data; + const response = await cb(...args); + if (response.errors === null) { + return response.data; } else { - throw new ClerkAPIResponseError(statusText || '', { - data: errors, + const { errors, clerkTraceId } = response; + // TODO: To be removed with withLegacyReturn + const { status, statusText } = response as any; + const error = new ClerkAPIResponseError(statusText || '', { + data: [], status: status || '', clerkTraceId, }); + error.errors = errors; + throw error; } };