在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
相关产品推荐
相关产品推荐

