Next.js中怎么全局捕获API调用错误?ErrorBoundary没生效
我在Next.js 13项目里用getServerSideProps调API,但遇到接口报错时页面直接白屏了。按照文档写了组件包裹的ErrorBoundary,但错误信息没被捕获到,控制台只看到”Error: Failed to fetch data”。
尝试在getServerSideProps里加try/catch包裹fetch调用,但错误还是穿透了:
export async function getServerSideProps() {
try {
const res = await fetch('/api/data');
return { props: { data: await res.json() } }
} catch (err) {
console.log('caught here'); // 这个日志都没触发
return { props: { error: 'Failed' } }
}
}
页面组件里用useState存error状态也没用,直接报错导致SSR渲染失败。应该用什么方式全局处理这种API错误呢?
关键点来了:getServerSideProps里必须吞掉错误,并返回一个带error标志的props,别让错误往外抛。
你试了try/catch但日志没触发,说明错误可能不是fetch本身抛的,而是res.json()或者后续逻辑抛的,或者你根本没走到catch块(比如res.ok是false但fetch没报错)。
改法如下:
然后在页面组件里:
另外提醒一句,你用的fetch('/api/data')在SSR环境里可能根本不是调你自己的API路由,因为SSR执行时没有request上下文,相对路径容易出问题,最好写全路径,或者改用getStaticProps + revalidate(如果数据不需要实时性),或者改在客户端用useEffect去fetch(这样ErrorBoundary就能兜住了)。
要是你非要走SSR又想全局处理,可以在_next/server/pages里写个中间件,或者在pages/_app.js里用getInitialProps统一包装——不过得小心,getInitialProps一用整个app就变成SSG模式了,性能和行为都会变,别乱用。
老项目里我一般直接让getServerSideProps里吃掉所有错,返回error字段,前端判断显示。ErrorBoundary只管客户端渲染阶段的错误,服务端的它真管不了。
第一种解决方案是利用getServerSideProps的返回特性,在服务端就处理好错误情况。具体来说可以这样写:
这里的关键点是,即使fetch本身没有抛出异常,也要判断response的状态码。因为4xx或5xx的响应在fetch眼里并不算异常,不会进入catch分支。
第二种方法更适合做全局错误处理,可以通过自定义App组件来实现。在pages/_app.js中:
这种方式的好处是可以集中处理所有页面的错误,不过要注意的是,这会影响所有使用getServerSideProps的页面。
另外补充一个细节,你原来的代码中try/catch没生效可能是因为fetch的url是相对路径'/api/data',在服务端渲染时可能会导致DNS解析问题。建议使用完整的绝对路径,或者通过process.env配置API基础路径。
最后说个开发小技巧,可以在next.config.js里配置onError回调,方便调试服务端错误:
这样做虽然会稍微影响生产环境性能,但能显著提升排查服务端错误的效率。记得上线前改回去就是了。