Обработка ошибок в Next.js
Next.js App Router использует файловую систему для обработки ошибок. Файлы error.tsx и not-found.tsx автоматически создают Error Boundaries на уровне каждого сегмента маршрута.
error.tsx
Файл error.tsx перехватывает ошибки в рантайме и показывает fallback UI вместо сломанной страницы:
'use client'
export default function Error({
error,
reset
}: {
error: Error & { digest?: string }
reset: () => void
}) {
return (
<div>
<h2>Что-то пошло не так</h2>
<p>{error.message}</p>
<button onClick={() => reset()}>Попробовать снова</button>
</div>
)
}
Ключевые моменты:
error.tsxобязательно должен быть клиентским компонентом ('use client')resetпытается заново отрендерить сегментerror.digestсодержит хеш ошибки для логирования на сервере
Вложенная обработка ошибок
Ошибки всплывают вверх к ближайшему error.tsx:
Ошибка в /problems/123 будет перехвачена app/problems/error.tsx. Если его нет, всплывет к app/error.tsx.
Важно:
error.tsx не перехватывает ошибки в layout.tsx того же сегмента, потому что error boundary вложен внутрь layout. Для обработки ошибок в layout нужен error.tsx в родительском сегменте.
global-error.tsx
Для обработки ошибок в корневом layout:
// app/global-error.tsx
'use client'
export default function GlobalError({
error,
reset
}: {
error: Error & { digest?: string }
reset: () => void
}) {
return (
<html>
<body>
<h2>Произошла критическая ошибка</h2>
<button onClick={() => reset()}>Перезагрузить</button>
</body>
</html>
)
}
global-error.tsx заменяет весь корневой layout, поэтому должен содержать <html> и <body>.
not-found.tsx
Для обработки 404 ошибок:
// app/not-found.tsx
import Link from 'next/link'
export default function NotFound() {
return (
<div>
<h2>Страница не найдена</h2>
<p>Мы не смогли найти запрашиваемую страницу на Hack Frontend.</p>
<Link href="/">Вернуться на главную</Link>
</div>
)
}
not-found.tsx срабатывает автоматически, когда Next.js не находит роут. Также можно вызвать вручную:
import { notFound } from 'next/navigation'
export default async function DocPage({
params
}: {
params: { slug: string }
}) {
const doc = await getDoc(params.slug)
if (!doc) {
notFound()
}
return <article>{doc.content}</article>
}
Порядок обработки
layout.tsx
error.tsx ← перехватывает ошибки из:
loading.tsx
not-found.tsx
page.tsx ← ошибки отсюда поднимаются к error.tsx
Обработка ошибок в Server Actions
Server Actions возвращают ошибки через return, а не throw:
'use server'
export async function updateProfile(formData: FormData) {
try {
await db.user.update({ ... })
revalidatePath('/settings')
return { success: true }
} catch (error) {
return { error: 'Не удалось обновить профиль' }
}
}
Полезные ресурсы
- nextjs.org/docs — Error Handling
- error.tsx API Reference