如何在React Query全局onError处理器中获取错误响应状态码
核心原因
QueryCache 的 onError 回调接收到的 error 对象结构由你使用的 HTTP 请求客户端决定,React Query 不会主动封装错误对象的属性,所以需要结合你发起请求的工具调整取值逻辑。
常见场景解决方案
场景1:使用 Axios 发起请求
Axios 抛出的请求错误会将响应信息挂载到 response 属性下,调整判断逻辑即可:
const queryClient = new QueryClient({ queryCache: new QueryCache({ onError: async (error, query) => { // 先判断响应存在再取状态码,避免网络无响应时报错 if (error?.response?.status === 401) { console.log("Refreshing Token"); await api.get("/api/refresh-token"); queryClient.refetchQueries(query.queryKey); } }, }) });
如果是TS项目,可以加类型守卫保证类型安全:
import type { AxiosError } from 'axios' // 在onError里判断 if (axios.isAxiosError(error) && error.response?.status === 401) { // 刷新令牌逻辑 }
场景2:使用原生 Fetch API 发起请求
Fetch API 默认只会在网络异常时抛出错误,401、500这类业务错误状态码不会自动抛错,需要你在 queryFn 中手动处理并把状态码挂载到错误对象上:
// 你的queryFn示例 const fetchData = async (url) => { const res = await fetch(url) if (!res.ok) { const error = new Error('请求失败') // 手动挂载状态码到错误对象 error.status = res.status throw error } return res.json() }
此时你最初写的 error.status === 401 判断即可正常生效。
优化建议
当前实现如果同时有多个请求返回401,会重复调用刷新令牌接口,建议加个刷新锁,保证同一时间只会触发一次令牌刷新,刷新完成后再统一重发所有失败的请求。
内容的提问来源于stack exchange,提问作者JonasLevin
相关产品推荐
相关产品推荐

