使用TanStack Query的useMutation时onError返回null问题排查
TanStack Query onError捕获到null错误的原因与解决方法
核心原因
你的apiRequest没有正确抛出错误,导致TanStack Query无法识别请求失败。TanStack Query完全依赖Promise的状态判断请求结果:只要Promise resolve了,哪怕网络返回500,Query也会认为请求成功;只有当Promise reject时,Query才会触发onError并传入错误对象。
具体排查点
- 检查
apiRequest的实现:如果用fetch或者axios,但没处理HTTP错误状态码(比如5xx、4xx),就会出现网络返回500但Promise依然resolve的情况。比如fetch默认只有断网这类网络错误才会reject,HTTP状态码错误不会自动触发reject,必须手动处理。 - 你提到的额外参数
id:如果这个参数导致apiRequest内部逻辑出错,但代码没抛出错误,也会让Promise保持resolve状态。
解决方案
1. 让apiRequest正确抛出HTTP错误
用fetch的情况:
async function apiRequest(id, payload) { const response = await fetch(`/your-api/${id}`, { method: 'PUT', body: JSON.stringify(payload), headers: { 'Content-Type': 'application/json' } }); // 手动判断响应状态,非2xx就抛出错误 if (!response.ok) { // 尝试解析错误响应,失败则用文本 const errorDetail = await response.json().catch(() => response.text()); throw new Error(`请求失败:${response.status}`, { cause: errorDetail }); } return response.json(); }
用axios的情况:
axios默认会自动reject非2xx状态码,但如果手动修改过validateStatus配置,要恢复默认逻辑:
async function apiRequest(id, payload) { return axios.put(`/your-api/${id}`, payload, { // 确保只把2xx状态视为成功 validateStatus: (status) => status >= 200 && status < 300 }); }
2. 修正onError的参数写法
你当前的onError参数结构错了,TanStack Query的onError回调第一个参数就是错误对象,不是包含error属性的对象。改成这样:
onError: (error) => { console.log("错误信息:", error.message); // 如果需要错误详情,可通过error.cause获取(对应上面抛出错误时的cause) console.log("错误详情:", error.cause); }
3. 验证参数id的有效性
确认id是合法可用的变量,如果id是undefined或无效值,导致请求地址错误但apiRequest没抛出错误,也会让Promise resolve,进而导致onError不触发或拿到null。
总结
问题和额外参数本身无关,核心是apiRequest没有把HTTP 500错误转化为Promise的reject。只要让请求函数在遇到HTTP错误时抛出异常,TanStack Query就能正确捕获错误并传递给onError。
内容的提问来源于stack exchange,提问作者GoldCasket
相关产品推荐
相关产品推荐

