You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确处理react-query中服务器返回的未定义错误响应

处理前端请求中未定义错误响应的最佳实践

这个问题我之前也踩过坑,本质是没搞清楚Axios错误对象的结构差异——当后端完全没启动、网络中断,或者请求根本没到达后端时,Axios抛出的错误里没有response属性,这时候直接链式访问error.response.data自然会触发“无法读取未定义属性”的报错。你之前写的判断条件之所以没用,是因为在检查error.response.data之前,error.response本身就已经是undefined了,链式访问会直接抛出错误,根本走不到判断逻辑里。

下面给你几个靠谱的解决方案,按简洁性和实用性排序:

1. 用可选链+空值合并运算符(最简洁)

ES2020及以上版本支持的可选链操作符?.可以安全地访问嵌套属性,当某个属性不存在时会返回undefined而不报错;再配合空值合并运算符??,可以给一个友好的默认提示:

const Home = () => { 
  const { isLoading, isError, error, data } = useQuery('user', fetchUser) 

  if (isLoading) { 
    return <ResponseBlock message="Loading data..." /> 
  } 

  if (isError) { 
    // 逐层安全访问,兜底默认提示
    const errorMsg = error?.response?.data?.message ?? '服务器连接失败,请稍后重试'
    return <ResponseBlock message={errorMsg} /> 
  } 

  // 处理成功状态的逻辑
  return <div>用户数据:{JSON.stringify(data)}</div>
} 
export default Home

2. 区分不同错误类型(最细致)

Axios的错误其实分三类场景,你可以针对性给出更精准的提示,提升用户体验:

  • 请求已发送,后端返回错误状态码(4xx/5xx):此时error.response存在
  • 请求已发送但未收到响应(比如后端没启动、网络断了):此时error.response不存在,但error.request存在
  • 请求配置或响应解析出错:属于其他类型错误,error.message会有描述

对应的代码实现:

const Home = () => { 
  const { isLoading, isError, error, data } = useQuery('user', fetchUser) 

  if (isLoading) { 
    return <ResponseBlock message="Loading data..." /> 
  } 

  if (isError) { 
    let errorMsg = '请求出错,请稍后重试'
    
    if (error.response) {
      // 后端返回的业务错误
      errorMsg = error.response.data?.message || `请求失败,状态码:${error.response.status}`
    } else if (error.request) {
      // 无法连接到服务器
      errorMsg = '无法连接到服务器,请检查服务器状态或网络'
    } else {
      // 其他错误(比如请求配置错误)
      errorMsg = error.message
    }

    return <ResponseBlock message={errorMsg} /> 
  } 

  // 成功渲染逻辑
  return <div>用户数据:{JSON.stringify(data)}</div>
} 
export default Home

3. 给请求加超时(额外优化)

为了避免请求一直处于pending状态,你可以在fetchUser函数里给Axios请求加超时配置,超时后会直接触发错误,方便用户及时得到反馈:

export async function fetchUser() { 
  const userID = new URLSearchParams(window.location.search).get('userID') 
  const { data } = await axios.get( 
    `${process.env.REACT_APP_API_BASE_URL}?userID=${userID}`,
    { timeout: 5000 } // 设置5秒超时
  ) 
  return data 
}

另外提个小细节:react-query已经提供了isError状态,用if (isError)判断错误场景比if (error)更符合它的设计规范,虽然两者效果差不多,但前者语义更清晰。

内容的提问来源于stack exchange,提问作者katie hudson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 18:57:42