Next.js 13.4 App Router 的错误处理指南
本文将介绍如何在 Next.js 的 App Router 中使用新的错误文件约定来处理错误。
错误处理是任何 Web 应用程序开发的关键方面。过去,Next.js 通过自定义错误页面(如 404 和 500 页面)来帮助开发者处理错误。但是,这些页面在 Pages Router 中存在局限性,例如对特定 UI 集成的支持有限、对 React 错误边界支持过时以及发生错误时应用程序功能有限。
Next.js 13.4 版本发布后,新的 App Router 已正式投入生产使用。App Router 增强了对错误处理和其他 Web 应用程序构建基本部分的支持和开发人员体验。
app
目录中的 error.tsx
文件创建了一个 React 错误边界,防止应用程序在发生错误时崩溃。它还可以充当回退组件,在边界内抛出错误时呈现。AuthRequiredError
来处理各种路由中的身份验证错误。global-error.tsx
文件。如果错误发生在服务器组件中或在数据获取期间,Next.js 将把相应的 Error 对象转发到最近的 error.tsx
边界。为了便于理解新的错误处理 API,我们将探讨它在 Next.js 用户身份验证应用程序中的实现。
用户身份验证容易出现许多错误,因此在构建其他应用程序时,学习如何在这种情况下去处理错误将对您大有裨益。
在开始之前,请通过克隆此处链接的仓库(主分支)来获取我们将在此文中使用的演示应用程序的代码。运行应用程序后,您应该会看到下图所示的错误。
在此演示应用程序中,主页面(显示表格)只能由已登录的用户访问,但发生了一些错误(在这种情况下是人为制造的,但它也可能合法地发生),导致会话变量被赋值为 null。
注意:为简单起见,演示应用程序中不会实现身份验证。
这当然会导致错误,现在,应用程序完全崩溃了,因为它不知道如何处理错误!
现在,我们将学习如何处理该错误以防止我们的应用程序崩溃,从而显著提高应用程序的用户体验。
为了防止应用程序崩溃,在 app/
目录中,创建一个 error.tsx
文件。创建此文件会自动创建一个 React 错误边界,该边界将包装主页面。然后,在 error.tsx
文件中,导出以下函数:
"use client"; export default function Error() { return ( <div className="grid h-screen px-4 bg-white place-content-center"> <div className="text-center"> <h1 className="font-black text-gray-200 text-9xl">401</h1> <p className="text-2xl font-bold tracking-tight text-gray-900 sm:text-4xl"> 未授权! </p> <p className="mt-4 text-gray-500"> 您必须登录才能访问此页面 </p> <button type="button" className="inline-block px-5 py-3 mt-6 text-sm font-medium text-white bg-indigo-600 rounded hover:bg-indigo-700 focus:outline-none focus:ring" > 重试 </button> </div> </div> ); }
注意:错误组件必须是客户端组件!请务必将它们标记为客户端组件。
导出的函数将充当回退组件。如果在边界内抛出错误,则会捕获该错误并呈现回退组件,该组件应如下所示。
发生错误时,会将两个 props 传递给错误回退组件——错误对象本身以及尝试从错误中恢复的函数(通常称为 reset):
"use client"; type ErrorProps = { error: Error; reset: () => void; }; export default function Error({ error, reset }: ErrorProps) { // ... }
我们现在可以通过 error prop 访问错误消息,并将其显示在屏幕上,如下所示:
<p className="mt-4 text-gray-500"> {error.message || "您必须登录才能访问此页面"} </p>
当调用该函数时,reset 函数将尝试重新渲染由错误边界包围的原始内容。如果成功,则回退错误组件将被重新渲染的内容替换。
我们可以使用 onClick 处理程序在我们的按钮中实现 reset 函数调用:
<button type="button" onClick={() => reset()} className="inline-block px-5 py-3 mt-6 text-sm font-medium text-white bg-indigo-600 rounded hover:bg-indigo-700 focus:outline-none focus:ring cursor-pointer" > 重试 </button>
这样,我们就成功地处理了我们的错误!
在一个实际的用户身份验证应用程序中,可能会有许多必须受保护的路由,如果发生身份验证错误,则需要在多个实例中使用相同的身份验证错误消息。
为了抽象错误消息(并且不重复编写),我们可以轻松地创建一个与身份验证相关的自定义异常。
为此,创建一个名为 lib
的目录,并在该目录中创建一个名为 exceptions.ts
的文件。在此文件中,我们可以创建和导出自定义身份验证错误异常,如下所示:
export class AuthRequiredError extends Error { constructor(message = "需要身份验证才能访问此页面") { super(message); this.name = "AuthRequiredError"; } }
现在,我们可以在主页面上抛出这个新的自定义 AuthRequiredError
,而不是常规的 Error
:
export default function Home() { if (!session) throw new AuthRequiredError(); // ... }
该错误将给我们提供构造函数中传递的默认消息,或者我们以后可能需要传递的更具体的错误。
最后,让我们注意一下布局和服务器错误的一些额外内容。
错误可能发生在应用程序的任何位置(不仅仅是 page.tsx
文件),Next.js 使用的文件路由系统会影响 error.tsx
边界在嵌套路由和布局中的工作方式。
错误会冒泡到最近的父错误边界,这可以在下图中看到。
这种错误冒泡的性质意味着 error.tsx
边界不会捕获同一部分中布局文件中的错误,因为错误边界会包装布局文件。
如果根布局或模板中发生错误,请使用 global-error.tsx
文件,如下图所示。
global-error.tsx
边界会包装整个应用程序,因此请确保在使用此文件时添加您自己独特的 和
标签。此错误边界会捕获其他嵌套
error.tsx
边界未捕获的任何错误,因此它不会经常被激活。
如果错误发生在服务器组件中或在数据获取期间,Next.js 将把相应的 Error 对象转发到最近的 error.tsx
边界。
尽管许多开发人员认为实现错误处理很麻烦,但它是应用程序的重要组成部分,成功实现错误处理将显着提高应用程序的用户体验。
借助 App Router 和 error.tsx
文件约定,Next.js 使此操作变得非常简单。
您可以查阅 Next.js 关于错误处理的文档,以了解有关错误处理的更多信息,您也可以在 GitHub 上查看本文的完成代码。
(此处省略了FAQs 部分,因为原文的FAQs 部分与文章内容重复度较高,且部分问题与App Router 的错误处理机制关联性较弱。如果需要,可以根据原文补充。)
以上是掌握Next.js错误处理应用程序路由器的详细内容。更多信息请关注PHP中文网其他相关文章!