خطاها به دو دسته تقسیم میشوند:
برای مدیریت خطاهای فرم، از useActionState استفاده کنید و بهجای throw کردن خطا، خروجی تابع را مدلسازی کنید:
// app/actions.ts
'use server'
export async function createPost(prevState, formData) {
const title = formData.get('title')
const content = formData.get('content')
const res = await fetch('https://api.vercel.app/posts', {
method: 'POST',
body: { title, content },
})
if (!res.ok) {
return { message: 'Failed to create post' }
}
}// app/ui/form.tsx
'use client'
import { useActionState } from 'react'
import { createPost } from '@/app/actions'
const initialState = { message: '' }
export function Form() {
const [state, formAction, pending] = useActionState(createPost, initialState)
return (
<form action={formAction}>
<input name="title" required />
<textarea name="content" required />
{state?.message && <p>{state.message}</p>}
<button disabled={pending}>Create Post</button>
</form>
)
}میتوان پاسخ fetch را بررسی کرد و در صورت خطا، پیام مناسب نمایش داد یا مسیر را تغییر داد:
// app/page.tsx
export default async function Page() {
const res = await fetch('https://...')
if (!res.ok) return 'There was an error.'
return '...'
}برای نمایش UI سفارشی هنگام نبود داده، از notFound() استفاده کنید:
// app/blog/[slug]/page.tsx
import { getPostBySlug } from '@/lib/posts'
export default async function Page({ params }) {
const post = getPostBySlug(params.slug)
if (!post) notFound()
return <div>{post.title}</div>
}// app/blog/[slug]/not-found.tsx
export default function NotFound() {
return <div>404 - Page Not Found</div>
}برای مدیریت خطاهای غیرمنتظره، فایل error.tsx را در مسیر مورد نظر ایجاد کنید:
// app/dashboard/error.tsx
'use client'
import { useEffect } from 'react'
export default function Error({ error, reset }) {
useEffect(() => {
console.error(error)
}, [error])
return (
<div>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</button>
</div>
)
}مرزهای خطا خطاهای داخل event handler را نمیگیرند. برای این موارد، از useState برای ذخیرهٔ خطا استفاده کنید:
// app/ui/button.tsx
'use client'
import { useState } from 'react'
export function Button() {
const [error, setError] = useState(null)
const handleClick = () => {
try {
throw new Error('Exception')
} catch (reason) {
setError(reason)
}
}
if (error) return <p>Error occurred</p>
return <button onClick={handleClick}>Click me</button>
}خطاهای داخل startTransition به نزدیکترین مرز خطا منتقل میشوند:
// app/ui/button.tsx
'use client'
import { useTransition } from 'react'
export function Button() {
const [pending, startTransition] = useTransition()
const handleClick = () =>
startTransition(() => {
throw new Error('Exception')
})
return <button onClick={handleClick}>Click me</button>
}برای مدیریت خطا در لایهٔ ریشه، از فایل global-error.tsx استفاده کنید. این فایل باید شامل تگهای <html> و <body> باشد:
// app/global-error.tsx
'use client'
export default function GlobalError({ error, reset }) {
return (
<html>
<body>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</button>
</body>
</html>
)
}Next.js ابزارهای متنوعی برای مدیریت خطاها ارائه میدهد. با استفاده از useActionState، notFound()، مرزهای خطا و فایلهای error.tsx و global-error.tsx میتوان تجربهای پایدار و قابل اعتماد برای کاربر فراهم کرد.