مدیریت خطاها در Next.js – خطاهای قابل پیش‌بینی، استثناهای ناگهانی و مرزهای خطا

در Next.js خطاها به دو دسته تقسیم می‌شوند: خطاهای قابل پیش‌بینی و استثناهای ناگهانی. این مقاله نحوهٔ مدیریت خطاهای فرم، نمایش پیام‌های خطا با useActionState، استفاده از notFound برای صفحات ۴۰۴، و تعریف مرزهای خطا برای کنترل استثناهای غیرمنتظره را بررسی می‌کند. همچنین نحوهٔ مدیریت خطاهای رویدادی و خطاهای سراسری در لایهٔ ریشه توضیح داده شده است.

expected errorerror boundaryuseActionStatenotFound

~4 دقیقه مطالعه • بروزرسانی ۳ آبان ۱۴۰۴

انواع خطاها در Next.js


خطاها به دو دسته تقسیم می‌شوند:

  • خطاهای قابل پیش‌بینی: مانند خطاهای اعتبارسنجی فرم یا شکست درخواست‌ها
  • استثناهای ناگهانی: خطاهایی که نشان‌دهندهٔ باگ یا شرایط غیرمنتظره هستند

مدیریت خطاهای قابل پیش‌بینی


در Server Functions


برای مدیریت خطاهای فرم، از 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 Boundaries)


برای مدیریت خطاهای غیرمنتظره، فایل 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


خطاهای داخل 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 می‌توان تجربه‌ای پایدار و قابل اعتماد برای کاربر فراهم کرد.


نوشته و پژوهش شده توسط دکتر شاهین صیامی