Skip to main content
Practice Problems

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:

tsx
'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.tsx must be a client component ('use client')
  • reset attempts to re-render the segment
  • error.digest contains an error hash for server-side logging

Nested Error Handling

Errors bubble up to the nearest error.tsx:

  • app

  • error.tsx

  • problems

  • error.tsx

  • page.tsx

  • [id]

  • page.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:

tsx
// 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:

tsx
// 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 IT Lead.</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:

tsx
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:

tsx
'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

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems