如何处理错误以终止函数执行?useMutation异常捕获问题
解决方法
方案1:开启throwOnError配置
useMutation 默认不会把错误抛给调用 mutate 的外部代码,所以外层的 try/catch 抓不到错误。只需在 useMutation 配置里加一行 throwOnError: true,就能让错误向外抛出,被 try/catch 捕获:
const useValidatePassword = () =>{ return useMutation({ mutationFn: async (data: any) => { const body: validatePasswordPayload = { UserName: data.username, Password: data.currentPassword, }; await apiAccountSettings.validatePassword(tenantName, body); }, onSuccess: () => { return true }, onError: (data) => { toast.error(t('Current password is incorrect')); }, mutationKey: ['ValidatePassword', { tenant: tenantName }], throwOnError: true, // 新增配置:允许错误向外抛出 }); } const {mutate: validatePassword, error} = useValidatePassword(); // 注意:Somefn 必须是 async 函数 const Somefn = async () =>{ try { await validatePassword(validatePayload); } catch (error) { toast.error(t("Something went wrong")); return; } }
开启后,onError 会正常触发,同时错误会被外层 try/catch 捕获。如果不需要重复提示,可以删掉 onError 里的 toast,统一在 catch 里处理。
方案2:手动在mutationFn抛出业务错误
如果你的接口返回 HTTP 200 但实际是业务错误(比如返回了错误码但状态码正常),得先在 mutationFn 里判断响应结果,手动抛出错误,这样 useMutation 才能触发 onError,同时配合 throwOnError 让外层捕获:
const useValidatePassword = () =>{ return useMutation({ mutationFn: async (data: any) => { const body: validatePasswordPayload = { UserName: data.username, Password: data.currentPassword, }; const response = await apiAccountSettings.validatePassword(tenantName, body); // 假设接口返回的 response 里有 code 字段表示业务状态,0 代表成功 if (response.code !== 0) { throw new Error('密码验证失败'); // 手动抛出错误 } }, onSuccess: () => { return true }, onError: (data) => { toast.error(t('Current password is incorrect')); }, mutationKey: ['ValidatePassword', { tenant: tenantName }], throwOnError: true, }); }
方案3:用mutateAsync+try/catch 替代mutate
useMutation 提供的 mutateAsync 会返回 Promise,出错时会直接 reject,外层 try/catch 可以直接捕获,不需要额外配置:
const useValidatePassword = () =>{ return useMutation({ mutationFn: async (data: any) => { const body: validatePasswordPayload = { UserName: data.username, Password: data.currentPassword, }; await apiAccountSettings.validatePassword(tenantName, body); }, onSuccess: () => { return true }, onError: (data) => { toast.error(t('Current password is incorrect')); }, mutationKey: ['ValidatePassword', { tenant: tenantName }], }); } // 解构出 mutateAsync 而不是 mutate const {mutateAsync: validatePassword, error} = useValidatePassword(); const Somefn = async () =>{ try { await validatePassword(validatePayload); } catch (error) { toast.error(t("Something went wrong")); return; } }
内容的提问来源于stack exchange,提问作者Aurumen
相关产品推荐
相关产品推荐

