如何在Zod的refine方法中设置错误信息而非抛出错误?
问题:Zod refine方法中如何设置自定义错误信息而非抛出错误导致应用退出?
我有如下Zod schema:
const createApSchema = z .object({ name: z.string().min(1).max(32), isActive: z.boolean().default(true), description: z.string().max(200).optional(), ip: z.string().refine(validator.isIP), accessMode: AccessModeEnum, apiUsername: z.string().optional(), apiPassword: z.string().optional(), apiVersion: ApiVersionEnum, community: z.string().optional(), }) .refine((data) => { // check to see if AP type is snmp to force the community field const isSnmp = data.accessMode !== AccessModeEnumMap[AccessModeEnum.enum.mikrotikApi] if (isSnmp && !data.community) throw new Error('community string is required!') // check to see if AP type is mikrotik to force the api credentials fields if (!isSnmp && (!data.apiUsername || !data.apiPassword)) throw new Error('api username and password are required!') if (!isSnmp && !data.apiVersion) throw new Error('api version is required!') return true })
规则要求:当accessMode属性选择"mikrotikApi"值时,apiUsername、apiPassword和apiVersion字段为必填;若选择"snmp"等其他值,则community字段为必填。
当前代码可实现验证,但在schema的refine方法中通过抛出错误提示验证失败会导致应用退出,我希望设置错误信息以便自行处理,而非让应用退出。
解决方案
Zod的refine方法支持传入第二个参数配置对象,通过message字段指定自定义错误信息,同时将验证逻辑改为返回false触发错误(而非抛出Error)。另外,将多个验证规则拆分为独立的refine调用,能让错误信息更清晰,也便于后续维护。
修改后的代码如下:
const createApSchema = z .object({ name: z.string().min(1).max(32), isActive: z.boolean().default(true), description: z.string().max(200).optional(), ip: z.string().refine(validator.isIP), accessMode: AccessModeEnum, apiUsername: z.string().optional(), apiPassword: z.string().optional(), apiVersion: ApiVersionEnum, community: z.string().optional(), }) // 验证SNMP模式下community必填 .refine( (data) => { const isSnmp = data.accessMode !== AccessModeEnumMap[AccessModeEnum.enum.mikrotikApi]; return !isSnmp || !!data.community; }, { message: 'community string is required!', path: ['community'] // 将错误关联到community字段,便于定位 } ) // 验证mikrotikApi模式下apiUsername和apiPassword必填 .refine( (data) => { const isMikrotik = data.accessMode === AccessModeEnumMap[AccessModeEnum.enum.mikrotikApi]; return !isMikrotik || (!!data.apiUsername && !!data.apiPassword); }, { message: 'api username and password are required!', path: ['apiUsername', 'apiPassword'] // 关联到对应字段 } ) // 验证mikrotikApi模式下apiVersion必填 .refine( (data) => { const isMikrotik = data.accessMode === AccessModeEnumMap[AccessModeEnum.enum.mikrotikApi]; return !isMikrotik || !!data.apiVersion; }, { message: 'api version is required!', path: ['apiVersion'] // 关联到对应字段 } );
使用示例
调用safeParse方法获取验证结果,该方法不会抛出错误,而是返回包含验证状态和信息的对象:
const formData = { // 你的表单数据 }; const validationResult = createApSchema.safeParse(formData); if (!validationResult.success) { // 提取所有错误信息自行处理 const errorList = validationResult.error.issues.map(issue => { return { field: issue.path.join('.'), message: issue.message }; }); console.log('验证失败:', errorList); // 这里可以将错误信息展示给用户或进行其他业务处理 }
内容的提问来源于stack exchange,提问作者Islam Y-
相关产品推荐
相关产品推荐

