Error Handling in Next.js
The Next.js App Router uses the file system for error handling. The error.tsx and not-found.tsx files automatically create Error Boundaries at each route segment level.
error.tsx
The error.tsx file catches runtime errors and shows fallback UI instead of a broken page:
'use client'
export default function Error({
error,
reset
}: {
error: Error & { digest?: string }
reset: () => void
}) {
return (
<div>
<h2>Something went wrong</h2>
<p>{error.message}</p>
<button onClick={() => reset()}>Try again</button>
</div>
)
}
Key points:
error.tsxmust be a client component ('use client')resetattempts to re-render the segmenterror.digestcontains an error hash for server-side logging
Nested Error Handling
Errors bubble up to the nearest error.tsx:
An error in /problems/123 will be caught by app/problems/error.tsx. If it does not exist, it bubbles up to app/error.tsx.
Important:
error.tsx does not catch errors in the layout.tsx of the same segment because the error boundary is nested inside the layout. To handle layout errors you need error.tsx in the parent segment.
global-error.tsx
To handle errors in the root layout:
// app/global-error.tsx
'use client'
export default function GlobalError({
error,
reset
}: {
error: Error & { digest?: string }
reset: () => void
}) {
return (
<html>
<body>
<h2>A critical error occurred</h2>
<button onClick={() => reset()}>Reload</button>
</body>
</html>
)
}
global-error.tsx replaces the entire root layout, so it must contain <html> and <body>.
not-found.tsx
To handle 404 errors:
// app/not-found.tsx
import Link from 'next/link'
export default function NotFound() {
return (
<div>
<h2>Page Not Found</h2>
<p>We could not find the requested page on Hack Frontend.</p>
<Link href="/">Return to homepage</Link>
</div>
)
}
not-found.tsx triggers automatically when Next.js cannot find a route. It can also be called manually:
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>
}
Handling Order
layout.tsx
error.tsx ← catches errors from:
loading.tsx
not-found.tsx
page.tsx ← errors here bubble up to error.tsx
Error Handling in Server Actions
Server Actions return errors via return, not throw:
'use server'
export async function updateProfile(formData: FormData) {
try {
await db.user.update({ ... })
revalidatePath('/settings')
return { success: true }
} catch (error) {
return { error: 'Failed to update profile' }
}
}
Useful Resources
- nextjs.org/docs — Error Handling
- error.tsx API Reference