Next.js预期错误与未捕获异常的处理方法
作者:Peter-Lu
一、错误的分类
错误可以分为两类:预期错误和未捕获的异常。
- 预期错误:在应用程序正常运行过程中可能会遇到的错误,例如用户输入的错误数据或请求失败。
- 未捕获的异常:程序中的意外错误,通常表示代码中存在 bug 或其他不应出现的异常。
二、处理预期错误
预期错误是可以预见的错误,这类错误应该被明确处理,而不是让它们未捕获或抛出异常。常见的预期错误场景包括服务端验证错误或请求失败等。
1. 处理来自 Server Actions 的预期错误
当在 Server Actions 中发生预期错误时,建议使用 useFormState
hook 来管理这些错误并返回给客户端,而不是通过 try/catch
语句块来捕获它们。
示例:创建用户时处理错误
// app/actions.js 'use server' import { redirect } from 'next/navigation' export async function createUser(prevState, formData) { const res = await fetch('https://...') const json = await res.json() if (!res.ok) { return { message: '请输入有效的邮箱' } } redirect('/dashboard') }
在这个例子中,如果请求失败,createUser
将返回一个错误消息,而不是抛出异常。
然后,在客户端组件中,可以通过 useFormState
来处理返回的状态,展示错误消息。
// app/ui/signup.js 'use client' import { useFormState } from 'react' import { createUser } from '@/app/actions' const initialState = { message: '', } export function Signup() { const [state, formAction] = useFormState(createUser, initialState) return ( <form action={formAction}> <label htmlFor="email">邮箱</label> <input type="text" id="email" name="email" required /> <p aria-live="polite">{state?.message}</p> <button>注册</button> </form> ) }
重要提示
- 上述示例中使用的
useFormState
hook 已包含在 Next.js App Router 中。如果使用的是 React 19,请使用useActionState
。 useFormState
提供的state
可用于在客户端组件中显示错误消息,提升用户体验。
2. 处理来自 Server Components 的预期错误
在 Server Component 中获取数据时,可以根据请求的响应结果决定是否渲染错误消息或进行页面重定向。
// app/page.js export default async function Page() { const res = await fetch(`https://...`) const data = await res.json() if (!res.ok) { return '发生了错误。' } return '...' }
三、处理未捕获的异常
未捕获的异常是指程序中不应发生的错误,通常表明存在 bug。对于这些异常,我们应使用错误边界进行捕获并提供备用 UI。
1. 使用错误边界
错误边界允许我们捕获子组件中的异常,并显示一个备用的 UI,而不是让整个组件树崩溃。
在 Next.js 中,可以通过在路由段中添加 error.tsx
文件来创建错误边界。
// app/dashboard/error.js 'use client' import { useEffect } from 'react' export default function Error({ error, reset }) { useEffect(() => { // 将错误记录到错误报告服务 console.error(error) }, [error]) return ( <div> <h2>出现了问题!</h2> <button onClick={reset}>重试</button> </div> ) }
错误冒泡
如果希望错误冒泡到父级错误边界,可以在渲染 Error
组件时使用 throw
抛出错误。
2. 处理嵌套路由中的错误
错误会冒泡到最近的父级错误边界。因此,可以在不同级别的路由段中放置 error.tsx
文件,以实现更细粒度的错误处理。
// app/dashboard/error.js // 错误边界组件
四、处理全局错误
虽然不常见,但我们可以使用位于根 app
目录中的 app/global-error.js
来处理根布局中的错误,确保即使在国际化场景下也能正常处理错误。
示例:处理全局错误
// app/global-error.js 'use client' export default function GlobalError({ error, reset }) { return ( <html> <body> <h2>出现了问题!</h2> <button onClick={() => reset()}>重试</button> </body> </html> ) }
重要提示
- 全局错误 UI 必须包含
<html>
和<body>
标签,因为它会在激活时替换根布局或模板。 global-error.js
文件提供了全局错误处理的能力,确保在整个应用中能够优雅地处理未捕获的异常。
到此这篇关于Next.js预期错误与未捕获异常的处理方法的文章就介绍到这了,更多相关Next.js预期错误与未捕获异常内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!