11import { formatRelative } from '@clerk/shared/date' ;
2- import { isClerkAPIResponseError , isClerkRuntimeError } from '@clerk/shared/error' ;
32import { useClerk , useSession , useUser } from '@clerk/shared/react' ;
43import type { EnvironmentResource , PasskeyResource , UserResource } from '@clerk/shared/types' ;
54
65import { FormSubmitError } from '../../../components/form' ;
76import { getMosaicEnvironment , useMosaicEnvironment } from '../../../hooks/use-mosaic-environment' ;
8- import { fill , useErrorText , useLocale , useMessages } from '../../../localization' ;
7+ import { fill , useLocale , useMessages } from '../../../localization' ;
8+ import { save , SaveError } from '../../../utils/errors' ;
99import type {
1010 UserProfilePasskey ,
1111 UserProfilePasskeyNameValidator ,
@@ -87,7 +87,6 @@ export function useUserProfilePasskeysModel(): UserProfilePasskeysModel {
8787 const environment = useMosaicEnvironment ( ) ;
8888 const locale = useLocale ( ) ;
8989 const messages = useMessages ( 'userProfilePasskeys' ) ;
90- const errorText = useErrorText ( ) ;
9190 const validateName : UserProfilePasskeyNameValidator = name =>
9291 new TextEncoder ( ) . encode ( name ) . length > 256 ? { type : 'error' , message : messages . nameTooLongError } : undefined ;
9392
@@ -115,30 +114,13 @@ export function useUserProfilePasskeysModel(): UserProfilePasskeysModel {
115114 clerk . session ?. id !== sessionId ||
116115 getPasskeysProjection ( current , currentEnvironment , clerk . isSatellite ) . status === 'hidden'
117116 ) {
118- throw new FormSubmitError ( { message : messages . accountUnavailableError } ) ;
117+ throw new SaveError ( {
118+ global : { code : 'passkey_account_unavailable' , message : messages . accountUnavailableError } ,
119+ } ) ;
119120 }
120121 return current ;
121122 } ;
122123
123- function actionError ( error : unknown ) : Error {
124- if ( isClerkAPIResponseError ( error ) ) {
125- const first = error . errors [ 0 ] ;
126- return new Error (
127- errorText ( {
128- code : first ?. code ,
129- paramName : first ?. meta ?. paramName ,
130- message : first ?. longMessage || first ?. message || messages . saveError ,
131- } ) ,
132- ) ;
133- }
134- return new Error (
135- errorText ( {
136- code : isClerkRuntimeError ( error ) ? error . code : undefined ,
137- message : error instanceof Error && error . message ? error . message : messages . saveError ,
138- } ) ,
139- ) ;
140- }
141-
142124 function formatPasskeyDate ( date : Date ) : string {
143125 const relative = formatRelative ( { date, relativeTo : new Date ( ) } ) ;
144126 if ( ! relative ) {
@@ -170,13 +152,11 @@ export function useUserProfilePasskeysModel(): UserProfilePasskeysModel {
170152 ? async ( ) => {
171153 const current = currentUser ( ) ;
172154 if ( clerk . isSatellite ) {
173- throw new Error ( messages . accountUnavailableError ) ;
174- }
175- try {
176- await current . createPasskey ( ) ;
177- } catch ( error ) {
178- throw actionError ( error ) ;
155+ throw new SaveError ( {
156+ global : { code : 'passkey_account_unavailable' , message : messages . accountUnavailableError } ,
157+ } ) ;
179158 }
159+ await save ( ( ) => current . createPasskey ( ) ) ;
180160 }
181161 : undefined ,
182162 onRename : async ( id , name ) => {
@@ -188,39 +168,14 @@ export function useUserProfilePasskeysModel(): UserProfilePasskeysModel {
188168 if ( feedback ) {
189169 throw new FormSubmitError < UserProfileRenamePasskeyValues > ( { fields : { name : feedback . message } } ) ;
190170 }
191- try {
192- await passkey . update ( { name } ) ;
193- } catch ( error ) {
194- if ( ! isClerkAPIResponseError ( error ) ) {
195- throw new FormSubmitError ( { message : actionError ( error ) . message } ) ;
196- }
197- const fields : { name ?: string } = { } ;
198- let message : string | undefined ;
199- for ( const item of error . errors ) {
200- const text = errorText ( {
201- code : item . code ,
202- paramName : item . meta ?. paramName ,
203- message : item . longMessage || item . message || messages . saveError ,
204- } ) ;
205- if ( item . meta ?. paramName === 'name' ) {
206- fields . name ??= text ;
207- } else {
208- message ??= text ;
209- }
210- }
211- throw new FormSubmitError < UserProfileRenamePasskeyValues > ( { message, fields } ) ;
212- }
171+ await save ( ( ) => passkey . update ( { name } ) , [ 'name' ] ) ;
213172 } ,
214173 onRemove : async id => {
215174 const passkey = currentUser ( ) . passkeys . find ( candidate => candidate . id === id ) ;
216175 if ( ! passkey ) {
217- throw new Error ( messages . unavailableError ) ;
218- }
219- try {
220- await passkey . delete ( ) ;
221- } catch ( error ) {
222- throw actionError ( error ) ;
176+ throw new SaveError ( { global : { code : 'passkey_unavailable' , message : messages . unavailableError } } ) ;
223177 }
178+ await save ( ( ) => passkey . delete ( ) ) ;
224179 } ,
225180 } ;
226181}
0 commit comments