From d88ba3cce8095341ea53496c6196351ddc3007dd Mon Sep 17 00:00:00 2001 From: panteliselef Date: Thu, 7 Nov 2024 13:26:57 +0200 Subject: [PATCH 1/2] chore(clerk-js): Use fapi error long message instead of statusText. Customized error for using production keys in dev. --- .changeset/nervous-numbers-fix.md | 5 +++++ packages/clerk-js/src/core/resources/Base.ts | 19 +++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 .changeset/nervous-numbers-fix.md diff --git a/.changeset/nervous-numbers-fix.md b/.changeset/nervous-numbers-fix.md new file mode 100644 index 00000000000..9e36dda0990 --- /dev/null +++ b/.changeset/nervous-numbers-fix.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Use fapi error long message instead of statusText when throwing API errors. diff --git a/packages/clerk-js/src/core/resources/Base.ts b/packages/clerk-js/src/core/resources/Base.ts index 7f032cd8c40..5b742fe5908 100644 --- a/packages/clerk-js/src/core/resources/Base.ts +++ b/packages/clerk-js/src/core/resources/Base.ts @@ -1,4 +1,5 @@ import { isValidBrowserOnline } from '@clerk/shared/browser'; +import { isProductionFromPublishableKey } from '@clerk/shared/keys'; import type { ClerkAPIErrorJSON, ClerkResourceJSON, ClerkResourceReloadParams, DeletedObjectJSON } from '@clerk/types'; import { clerkMissingFapiClientInResources } from '../errors'; @@ -67,8 +68,22 @@ export abstract class BaseResource { } if (status >= 400) { - throw new ClerkAPIResponseError(statusText, { - data: payload?.errors as ClerkAPIErrorJSON[], + const errors = payload?.errors as ClerkAPIErrorJSON[]; + const safeErrorMessage = errors?.[0]?.long_message; + + if (errors?.[0]?.code === 'origin_invalid' && isProductionFromPublishableKey(BaseResource.clerk.publishableKey)) { + const prodDomain = BaseResource.clerk.frontendApi.replace('clerk.', ''); + throw new ClerkAPIResponseError( + `Clerk: Production Keys are only allowed for domain "${prodDomain}". \nAPI Error: ${safeErrorMessage}`, + { + data: errors, + status: status, + }, + ); + } + + throw new ClerkAPIResponseError(safeErrorMessage || statusText, { + data: errors, status: status, }); } From d30995919bb84e62e034ae0f8bdc1d8e12143e25 Mon Sep 17 00:00:00 2001 From: panteliselef Date: Mon, 11 Nov 2024 17:00:15 +0200 Subject: [PATCH 2/2] refactor --- packages/clerk-js/src/core/resources/Base.ts | 35 ++++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/packages/clerk-js/src/core/resources/Base.ts b/packages/clerk-js/src/core/resources/Base.ts index 5b742fe5908..87d44435a10 100644 --- a/packages/clerk-js/src/core/resources/Base.ts +++ b/packages/clerk-js/src/core/resources/Base.ts @@ -16,6 +16,30 @@ export type BaseMutateParams = { path?: string; }; +function assertProductionKeysOnDev(statusCode: number, payloadErrors?: ClerkAPIErrorJSON[]) { + if (!payloadErrors) { + return; + } + + if (!payloadErrors[0]) { + return; + } + + const safeError = payloadErrors[0]; + const safeErrorMessage = safeError.long_message; + + if (safeError.code === 'origin_invalid' && isProductionFromPublishableKey(BaseResource.clerk.publishableKey)) { + const prodDomain = BaseResource.clerk.frontendApi.replace('clerk.', ''); + throw new ClerkAPIResponseError( + `Clerk: Production Keys are only allowed for domain "${prodDomain}". \nAPI Error: ${safeErrorMessage}`, + { + data: payloadErrors, + status: statusCode, + }, + ); + } +} + export abstract class BaseResource { static clerk: Clerk; id?: string; @@ -71,16 +95,7 @@ export abstract class BaseResource { const errors = payload?.errors as ClerkAPIErrorJSON[]; const safeErrorMessage = errors?.[0]?.long_message; - if (errors?.[0]?.code === 'origin_invalid' && isProductionFromPublishableKey(BaseResource.clerk.publishableKey)) { - const prodDomain = BaseResource.clerk.frontendApi.replace('clerk.', ''); - throw new ClerkAPIResponseError( - `Clerk: Production Keys are only allowed for domain "${prodDomain}". \nAPI Error: ${safeErrorMessage}`, - { - data: errors, - status: status, - }, - ); - } + assertProductionKeysOnDev(status, errors); throw new ClerkAPIResponseError(safeErrorMessage || statusText, { data: errors,