错误处理
error.js
文件约定允许您在嵌套路由中优雅地处理意外的运行时错误。
- 自动使用 React 错误边界包裹路由片段及其嵌套子元素
- 利用文件系统层级结构创建针对特定片段的错误 UI,实现精细控制
- 将错误隔离在受影响片段内,同时保持应用程序其余部分正常运行
- 添加功能以尝试从错误中恢复,无需完全刷新页面
通过在路由片段内添加 error.js
文件并导出 React 组件来创建错误 UI:

error.js
工作原理

error.js
会自动创建一个 React 错误边界,包裹嵌套的子片段或page.js
组件- 从
error.js
文件导出的 React 组件将作为备用组件使用 - 如果在错误边界内抛出错误,错误会被捕获,并渲染备用组件
- 当备用错误组件激活时,错误边界上方的布局会保持其状态并维持交互性,错误组件可以显示恢复功能
从错误中恢复
有时错误原因可能是暂时的。这种情况下,简单地重试可能会解决问题。
错误组件可以使用 reset()
函数提示用户尝试从错误中恢复。执行该函数时,会尝试重新渲染错误边界的内容。如果成功,备用错误组件将被重新渲染的结果替换。
嵌套路由
通过特殊文件创建的 React 组件会在特定的嵌套层级结构中渲染。
例如,包含 layout.js
和 error.js
文件的两个嵌套路由段会按照以下简化的组件层级结构渲染:

嵌套组件层级结构会影响嵌套路由中 error.js
文件的行为:
- 错误会向上冒泡到最近的父级错误边界。这意味着
error.js
文件会处理其所有嵌套子片段中的错误。通过在路由的不同层级文件夹中放置error.js
文件,可以实现更精细或更粗略的错误 UI。 error.js
边界不会处理同一片段中layout.js
组件抛出的错误,因为错误边界嵌套在该布局组件的内部。
处理布局中的错误
error.js
边界不会捕获同一片段中 layout.js
或 template.js
组件抛出的错误。这种有意的层级结构确保当错误发生时,兄弟路由间共享的重要 UI(如导航)保持可见和功能正常。
要处理特定布局或模板中的错误,请在布局的父级片段中放置 error.js
文件。
要处理根布局或模板中的错误,请使用 error.js
的变体 global-error.js
。
处理根布局中的错误
根目录下的 app/error.js
边界不会捕获根 app/layout.js
或 app/template.js
组件抛出的错误。
要专门处理这些根组件中的错误,请使用位于根 app
目录下的 error.js
变体 app/global-error.js
。
与根 error.js
不同,global-error.js
错误边界会包裹整个应用程序,其备用组件在激活时会替换根布局。因此需要注意,global-error.js
必须定义自己的 <html>
和 <body>
标签。
global-error.js
是最不精细的错误 UI,可以被视为整个应用程序的"全局捕获"错误处理。由于根组件通常较少动态变化,且其他 error.js
边界会捕获大多数错误,因此它很少被触发。
即使定义了 global-error.js
,仍然建议定义一个根 error.js
,其备用组件将在根布局内部渲染,包含全局共享的 UI 和品牌标识。
须知:
global-error.js
仅在生产环境中生效。在开发环境下,会显示我们的错误覆盖层。
处理服务端错误
如果在服务端组件中抛出错误,Next.js 会将 Error
对象(在生产环境中会去除敏感错误信息)作为 error
属性传递给最近的 error.js
文件。
保护敏感错误信息
在生产环境中,传递给客户端的 Error
对象仅包含通用的 message
和 digest
属性。
这是一种安全预防措施,避免将错误中可能包含的敏感细节泄露给客户端。
message
属性包含关于错误的通用信息,digest
属性包含自动生成的错误哈希值,可用于匹配服务端日志中的相应错误。
在开发环境下,传递给客户端的 Error
对象会被序列化,并包含原始错误的 message
,以便于调试。