使用Axios+TanStack Query useMutation无法捕获连接拒绝错误
问题根源
net::ERR_CONNECTION_REFUSED是浏览器底层的网络请求失败日志,属于浏览器自带输出,没法通过前端代码彻底消掉,但可以处理未捕获的Promise错误,避免控制台弹出“未捕获错误”的提示。- onSubmit里的try/catch没触发,大概率是你用了TanStack Query的
mutate方法——它是异步但不返回Promise,try/catch抓不到;换成mutateAsync(返回Promise)就能被捕获了。 - TanStack Query的onError没生效,可能是Axios的网络错误没被正确抛出,或者没配置Axios全局拦截器,导致错误没传到mutation的回调里。
解决办法
1. 修正onSubmit的错误捕获逻辑
把mutate换成mutateAsync,用try/catch包裹异步调用:
import { useMutation } from '@tanstack/react-query'; import { useForm } from 'react-hook-form'; import api from './path/to/your/axios-instance'; const LoginForm = () => { const { register, handleSubmit } = useForm(); const loginMutation = useMutation({ mutationFn: async (credentials) => { const res = await api.post('/login', credentials); return res.data; }, onError: (err) => { // 这里处理mutation层面的错误,比如给用户弹提示 console.error('登录失败:', err.message); }, }); const onSubmit = handleSubmit(async (formData) => { try { await loginMutation.mutateAsync(formData); // 登录成功后的逻辑,比如跳转到首页 } catch (err) { // 这里能捕获到mutateAsync抛出的错误 console.error('提交出错:', err); } }); return ( <form onSubmit={onSubmit}> <input {...register('username')} placeholder="用户名" /> <input {...register('password')} type="password" placeholder="密码" /> <button type="submit" disabled={loginMutation.isPending}> {loginMutation.isPending ? '登录中...' : '登录'} </button> </form> ); };
2. 给Axios添加全局错误拦截
统一处理网络错误和HTTP状态码错误,确保错误能被正确抛出并格式化:
import axios from 'axios'; const api = axios.create({ baseURL: '/api', // 替换为你的后端接口前缀 }); // 响应拦截器处理错误 api.interceptors.response.use( (res) => res, (err) => { // 网络错误(无response的情况,比如连接拒绝、超时) if (!err.response) { throw new Error('网络连接失败,请检查后端服务状态'); } // HTTP错误(4xx、5xx状态码) const errMsg = err.response.data?.message || `请求失败,状态码:${err.response.status}`; throw new Error(errMsg); } ); export default api;
3. 全局捕获未处理的Promise错误
在项目入口文件main.tsx中添加监听,阻止浏览器默认的未捕获错误提示:
import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; // 捕获全局未处理的Promise拒绝 window.addEventListener('unhandledrejection', (event) => { event.preventDefault(); // 阻止浏览器输出默认的未捕获错误日志 console.error('全局未处理错误:', event.reason); // 这里可以添加全局错误提示,比如弹出Toast或通知组件 }); ReactDOM.createRoot(document.getElementById('root')!).render( <React.StrictMode> <App /> </React.StrictMode> );
4. 配置TanStack Query的错误边界(可选)
如果项目使用了错误边界功能,可以给QueryClient添加默认配置,让mutation的错误自动触发错误边界:
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; const queryClient = new QueryClient({ defaultOptions: { mutations: { errorBoundary: true, }, }, }); function App() { return ( <QueryClientProvider client={queryClient}> {/* 你的路由、组件内容 */} </QueryClientProvider> ); }
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

