NextJs - Error Handling (错误处理)

Error.js 的作用

使用 error.js 文件规则,可以优雅地处理嵌套路由中的意外运行时错误。

在 React Error Boundary 中自动封装路由段及其嵌套子段。

使用文件系统层次结构来调整粒度,为特定网段量身定制错误 UI。

将错误隔离到受影响的网段,同时保持应用程序其他部分的功能。

添加功能,尝试在不重新加载整个页面的情况下从错误中恢复。

通过在路由段内添加 error.js 文件并导出 React 组件来创建错误用户界面:

// app/dashboard/error.tsx
'use client' // Error components must be Client Components
 
import { useEffect } from 'react'
 
export default function Error({
  error,
  reset,
}: {
  error: Error
  reset: () => void
}) {
  useEffect(() => {
    // Log the error to an error reporting service
    console.error(error)
  }, [error])
 
  return (
    <div>
      <h2>Something went wrong!</h2>
      <button
        onClick={
          // Attempt to recover by trying to re-render the segment
          () => reset()
        }
      >
        Try again
      </button>
    </div>
  )
}

Error.js 的工作原理

error.js 会自动创建一个 React 错误边界,该边界会封装嵌套的子段或 page.js 组件。
从 error.js 文件导出的 React 组件将用作后备组件。
如果在错误边界内出现错误,则会包含错误并呈现回退组件。
当回退错误组件处于活动状态时,错误边界上方的布局会保持其状态并保持交互,而错误组件则可以显示从错误中恢复的功能。 

从错误中恢复

错误的原因有时可能是暂时的。在这种情况下,只需再次尝试就能解决问题。
错误组件可以使用 reset() 函数提示用户尝试从错误中恢复。该函数执行后,将尝试重新渲染错误边界的内容。如果成功,回退错误组件将被重新渲染的结果所取代。

嵌套路由
通过特殊文件创建的 React 组件会以特定的嵌套层次结构呈现。
例如,一个嵌套路由有两个段,其中都包含 layout.js 和 error.js 文件,会以以下简化的组件层次结构呈现:

 嵌套组件层次结构会影响整个嵌套路由中 error.js 文件的行为:
错误会向最近的父错误边界冒泡。这意味着 error.js 文件将处理其所有嵌套子段的错误。通过将 error.js 文件放置在路由嵌套文件夹的不同层级,可以实现更细粒度或更小粒度的错误用户界面。
error.js 界面不会处理同一段落中 layout.js 组件抛出的错误,因为错误边界嵌套在该布局组件中。

处理根布局中的错误

根 app/error.js 界面不会捕获在根 app/layout.js 或 app/template.js 组件中抛出的错误。
要专门处理这些根组件中的错误,可使用应用程序根目录中名为 app/global-error.js 的 error.js 变体。
与根 error.js 不同的是,global-error.js 的错误边界覆盖了整个应用程序,其回退组件会在激活时替换根布局。因此,必须注意 global-error.js 必须定义自己的 <html> 和 <body> 标记。
global-error.js 是粒度最小的错误用户界面,可视为整个应用程序的 "万能 "错误处理。它不太可能经常被触发,因为根组件的动态性通常较低,其他 error.js 界面会捕捉到大多数错误。
即使定义了 global-error.js,仍建议定义一个根 error.js,其后备组件将在根布局中呈现,其中包括全局共享的用户界面。

// app/global-error.tsx
'use client'
 
export default function GlobalError({
  error,
  reset,
}: {
  error: Error
  reset: () => void
}) {
  return (
    <html>
      <body>
        <h2>Something went wrong!</h2>
        <button onClick={() => reset()}>Try again</button>
      </body>
    </html>
  )
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值