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..87d44435a10 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'; @@ -15,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; @@ -67,8 +92,13 @@ 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; + + assertProductionKeysOnDev(status, errors); + + throw new ClerkAPIResponseError(safeErrorMessage || statusText, { + data: errors, status: status, }); }