diff --git a/.changeset/proud-coats-look.md b/.changeset/proud-coats-look.md new file mode 100644 index 00000000000..2675c1fc155 --- /dev/null +++ b/.changeset/proud-coats-look.md @@ -0,0 +1,6 @@ +--- +"@clerk/elements": patch +"@clerk/shared": patch +--- + +Fixes issue where errors were incorrectly being returned as an `any` type. diff --git a/packages/elements/src/internals/errors/index.ts b/packages/elements/src/internals/errors/index.ts index a60b88a2083..daeb21fe094 100644 --- a/packages/elements/src/internals/errors/index.ts +++ b/packages/elements/src/internals/errors/index.ts @@ -1,3 +1,4 @@ +import type { MetamaskError } from '@clerk/shared'; import type { ClerkAPIError } from '@clerk/types'; export abstract class ClerkElementsErrorBase extends Error { @@ -21,8 +22,12 @@ export abstract class ClerkElementsErrorBase extends Error { } export class ClerkElementsError extends ClerkElementsErrorBase { - static fromAPIError(error: ClerkAPIError) { - return new ClerkElementsError(error.code, error.longMessage || error.message); + static fromAPIError(error: ClerkAPIError | MetamaskError) { + return new ClerkElementsError( + error.code.toString(), + // @ts-expect-error - Expected that longMessage isn't a property of MetamaskError + error.longMessage || error.message, + ); } constructor(code: string, message: string) { diff --git a/packages/elements/src/internals/machines/form/form.machine.ts b/packages/elements/src/internals/machines/form/form.machine.ts index f9096be34ad..25da38daae9 100644 --- a/packages/elements/src/internals/machines/form/form.machine.ts +++ b/packages/elements/src/internals/machines/form/form.machine.ts @@ -1,5 +1,6 @@ -import { isKnownError } from '@clerk/shared/error'; +import { isClerkAPIResponseError, isKnownError, isMetamaskError } from '@clerk/shared/error'; import { snakeToCamel } from '@clerk/shared/underscore'; +import type { ClerkAPIError } from '@clerk/types'; import type { MachineContext } from 'xstate'; import { assign, enqueueActions, setup } from 'xstate'; @@ -94,17 +95,22 @@ export const FormMachine = setup({ on: { 'ERRORS.SET': { actions: enqueueActions(({ enqueue, event }) => { + const isClerkAPIError = (err: any): err is ClerkAPIError => 'meta' in err; + if (isKnownError(event.error)) { const fields: Record = {}; const globalErrors: ClerkElementsError[] = []; + const errors = isClerkAPIResponseError(event.error) ? event.error?.errors : [event.error]; - for (const error of event.error.errors || [event.error]) { - const name = snakeToCamel(error.meta?.paramName); + for (const error of errors) { + const name = isClerkAPIError(error) ? snakeToCamel(error.meta?.paramName) : null; - if (!name) { + if (!name || isMetamaskError(error)) { globalErrors.push(ClerkElementsError.fromAPIError(error)); continue; - } else if (!fields[name]) { + } + + if (!fields[name]) { fields[name] = []; } diff --git a/packages/shared/src/error.ts b/packages/shared/src/error.ts index dd3fac4e4b3..f570fd99f02 100644 --- a/packages/shared/src/error.ts +++ b/packages/shared/src/error.ts @@ -31,7 +31,7 @@ export interface MetamaskError extends Error { data?: unknown; } -export function isKnownError(error: any) { +export function isKnownError(error: any): error is ClerkAPIResponseError | ClerkRuntimeError | MetamaskError { return isClerkAPIResponseError(error) || isMetamaskError(error) || isClerkRuntimeError(error); }