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

在Next.js中使用SWR获取响应错误数据的问题

问题分析与解决

核心原因

你的catch逻辑不触发,大概率是因为后端返回了2xx类HTTP状态码(比如200)——即便响应体里带了业务错误信息,fetcher封装的Promise仍会被标记为resolved(成功状态),只会进入then分支,不会走到catch。

Promise的catch仅在Promise被rejected时执行,通常只有请求发生网络错误,或后端返回4xx/5xx等非成功状态码时,才会触发reject。

步骤1:修正代码语法错误

你的fetcher调用存在模板字符串未闭合、参数格式错误的问题,先修正:

// 补全模板字符串,将body放入配置对象中
mutate(
  `${api}`,
  fetcher('POST', `${api}`, { body: JSON.stringify(data) })
)

另外catch块里的data.error.message是错误写法——data在catch中未定义,若进入catch应使用error参数。

步骤2:处理后端错误响应

有两种可行方案:

方案一:让后端返回非2xx状态码

协调后端在业务错误时返回4xx(如400 Bad Request)或5xx状态码,这样如果fetcher是基于fetch封装的,通常会将这类响应转为rejected Promise,自然触发catch逻辑。

方案二:在then中手动判断业务错误

如果后端无法修改状态码,就在then分支里检查响应体是否包含errors字段,手动处理业务错误:

const [errorMessage, setErrorMessage] = useState('')

mutate(
  `${api}`,
  fetcher('POST', `${api}`, { body: JSON.stringify(data) })
)
  .then((responseData) => {
    // 检查是否存在业务错误
    if (responseData.errors && responseData.errors.length > 0) {
      const errMsg = responseData.errors[0].message
      setErrorMessage(errMsg)
      console.error(errMsg)
      return // 终止后续成功逻辑执行
    }
    // 执行正常成功逻辑
    // ... do something
  })
  .catch((networkError) => {
    // 处理网络错误或HTTP状态码错误
    setErrorMessage('网络请求失败,请稍后重试')
    console.error(networkError)
  })

补充:检查fetcher封装逻辑

如果fetcher是自定义封装的,确认它是否正确处理了HTTP状态码。基于fetch的标准封装应包含状态码判断:

async function fetcher(method, url, options = {}) {
  const response = await fetch(url, {
    method,
    ...options,
    headers: {
      'Content-Type': 'application/json',
      ...options.headers,
    },
  })

  // 关键:非2xx状态码时抛出错误,触发Promise reject
  if (!response.ok) {
    const errorData = await response.json()
    throw new Error(errorData.errors?.[0]?.message || '请求失败')
  }

  return response.json()
}

如果你的fetcher缺少这一步判断,即便后端返回4xx/5xx,也会返回resolved Promise,导致catch不触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:33:55