1- import { isClerkAPIResponseError } from '@clerk/shared/error' ;
1+ import { type ClerkError , createClerkGlobalHookError , isClerkAPIResponseError } from '@clerk/shared/error' ;
22import type { Errors , SignInSignal , SignUpSignal } from '@clerk/shared/types' ;
33import { snakeToCamel } from '@clerk/shared/underscore' ;
44import { computed , signal } from 'alien-signals' ;
@@ -7,7 +7,7 @@ import type { SignIn } from './resources/SignIn';
77import type { SignUp } from './resources/SignUp' ;
88
99export const signInResourceSignal = signal < { resource : SignIn | null } > ( { resource : null } ) ;
10- export const signInErrorSignal = signal < { error : unknown } > ( { error : null } ) ;
10+ export const signInErrorSignal = signal < { error : ClerkError | null } > ( { error : null } ) ;
1111export const signInFetchSignal = signal < { status : 'idle' | 'fetching' } > ( { status : 'idle' } ) ;
1212
1313export const signInComputedSignal : SignInSignal = computed ( ( ) => {
@@ -21,7 +21,7 @@ export const signInComputedSignal: SignInSignal = computed(() => {
2121} ) ;
2222
2323export const signUpResourceSignal = signal < { resource : SignUp | null } > ( { resource : null } ) ;
24- export const signUpErrorSignal = signal < { error : unknown } > ( { error : null } ) ;
24+ export const signUpErrorSignal = signal < { error : ClerkError | null } > ( { error : null } ) ;
2525export const signUpFetchSignal = signal < { status : 'idle' | 'fetching' } > ( { status : 'idle' } ) ;
2626
2727export const signUpComputedSignal : SignUpSignal = computed ( ( ) => {
@@ -38,7 +38,7 @@ export const signUpComputedSignal: SignUpSignal = computed(() => {
3838 * Converts an error to a parsed errors object that reports the specific fields that the error pertains to. Will put
3939 * generic non-API errors into the global array.
4040 */
41- function errorsToParsedErrors ( error : unknown ) : Errors {
41+ function errorsToParsedErrors ( error : ClerkError | null ) : Errors {
4242 const parsedErrors : Errors = {
4343 fields : {
4444 firstName : null ,
@@ -62,29 +62,32 @@ function errorsToParsedErrors(error: unknown): Errors {
6262
6363 if ( ! isClerkAPIResponseError ( error ) ) {
6464 parsedErrors . raw = [ error ] ;
65- parsedErrors . global = [ error ] ;
65+ parsedErrors . global = [ createClerkGlobalHookError ( error ) ] ;
6666 return parsedErrors ;
6767 }
6868
69- error . errors . forEach ( error => {
70- if ( parsedErrors . raw ) {
71- parsedErrors . raw . push ( error ) ;
72- } else {
73- parsedErrors . raw = [ error ] ;
74- }
75-
76- if ( 'meta' in error && error . meta && 'paramName' in error . meta ) {
77- const name = snakeToCamel ( error . meta . paramName ) ;
78- parsedErrors . fields [ name as keyof typeof parsedErrors . fields ] = error ;
79- return ;
80- }
81-
82- if ( parsedErrors . global ) {
83- parsedErrors . global . push ( error ) ;
84- } else {
85- parsedErrors . global = [ error ] ;
86- }
87- } ) ;
69+ const hasFieldErrors = error . errors . some ( error => 'meta' in error && error . meta && 'paramName' in error . meta ) ;
70+ if ( hasFieldErrors ) {
71+ error . errors . forEach ( error => {
72+ if ( parsedErrors . raw ) {
73+ parsedErrors . raw . push ( error ) ;
74+ } else {
75+ parsedErrors . raw = [ error ] ;
76+ }
77+ if ( 'meta' in error && error . meta && 'paramName' in error . meta ) {
78+ const name = snakeToCamel ( error . meta . paramName ) ;
79+ parsedErrors . fields [ name as keyof typeof parsedErrors . fields ] = error ;
80+ }
81+ // Note that this assumes a given ClerkAPIResponseError will only have either field errors or global errors, but
82+ // not both. If a global error is present, it will be discarded.
83+ } ) ;
84+
85+ return parsedErrors ;
86+ }
87+
88+ // At this point, we know that `error` is a ClerkAPIResponseError and that it has no field errors.
89+ parsedErrors . raw = [ error ] ;
90+ parsedErrors . global = [ createClerkGlobalHookError ( error ) ] ;
8891
8992 return parsedErrors ;
9093}
0 commit comments