Next.js中怎么全局捕获API调用错误?ErrorBoundary没生效

书生シ银银 阅读 23

我在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错误呢?

我来解答 赞 4 收藏
二维码
手机扫码查看
1 条解答
嘉俊🍀
这个问题的根源在于Next.js的服务端渲染机制,ErrorBoundary只能捕获客户端组件的错误,而getServerSideProps是在服务端执行的,所以自然捕获不到。我们需要换个思路来处理。

第一种解决方案是利用getServerSideProps的返回特性,在服务端就处理好错误情况。具体来说可以这样写:

export async function getServerSideProps(context) {
try {
const res = await fetch('http://example.com/api/data');
if (!res.ok) {
// 注意这里要手动判断response状态
return { props: { error: '数据获取失败', errorCode: res.status } };
}
const data = await res.json();
return { props: { data } };
} catch (err) {
// 捕获网络错误或JSON解析错误
return { props: { error: err.message || '未知错误' } };
}
}


这里的关键点是,即使fetch本身没有抛出异常,也要判断response的状态码。因为4xx或5xx的响应在fetch眼里并不算异常,不会进入catch分支。

第二种方法更适合做全局错误处理,可以通过自定义App组件来实现。在pages/_app.js中:

class MyApp extends App {
static async getInitialProps({ Component, ctx }) {
let pageProps = {};
try {
if (Component.getServerSideProps) {
pageProps = await Component.getServerSideProps(ctx);
}
} catch (error) {
// 全局错误处理逻辑
pageProps = { error: error.message || '服务器错误' };
}
return { pageProps };
}

render() {
const { Component, pageProps } = this.props;
if (pageProps.error) {
return <ErrorPage error={pageProps.error} />;
}
return <Component {...pageProps} />;
}
}


这种方式的好处是可以集中处理所有页面的错误,不过要注意的是,这会影响所有使用getServerSideProps的页面。

另外补充一个细节,你原来的代码中try/catch没生效可能是因为fetch的url是相对路径'/api/data',在服务端渲染时可能会导致DNS解析问题。建议使用完整的绝对路径,或者通过process.env配置API基础路径。

最后说个开发小技巧,可以在next.config.js里配置onError回调,方便调试服务端错误:

module.exports = {
webpack(config, options) {
if (!options.dev) {
config.devtool = 'source-map';
config.optimization.minimize = false;
}
return config;
}
};


这样做虽然会稍微影响生产环境性能,但能显著提升排查服务端错误的效率。记得上线前改回去就是了。
点赞 1
2026-02-14 08:27