NextjsError Handling & error.tsx

Error Handling & error.tsx

Runtime errors are inevitable — a database call times out, a third party API returns malformed JSON, a bug slips through review. Without any handling, an uncaught error in a route segment crashes the whole page and shows the user a blank screen or an ugly stack trace. The App Router gives every route segment a built-in way to catch that: a error.tsx file placed alongside page.tsx.
Next.js automatically wraps the segment's content in a React Error Boundary. When a rendering error is thrown anywhere inside that segment — during render, in an effect, or inside a nested Server Component that streamed in — the boundary catches it and renders error.tsx instead of letting the error bubble up and take down the rest of the page.

app/dashboard/error.tsx

TSX
'use client'

import { useEffect } from 'react'

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  useEffect(() => {
    // Log the error to an error reporting service
    console.error(error)
  }, [error])

  return (
    <div>
      <h2>Something went wrong!</h2>
      <button type="button" onClick={() => reset()}>
        Try again
      </button>
    </div>
  )
}
Warning
error.tsx must be a Client Component — it needs the 'use client' directive at the top. Error boundaries are a React feature built on class component lifecycle methods under the hood, and that mechanism only works on the client. Forgetting the directive is one of the most common mistakes when adding error handling.
The error and reset arguments
Next.js passes your error.tsx component two props automatically — you never wire these up yourself.

Prop

Description

error

The Error instance that was thrown, optionally carrying a digest string that correlates to the matching server-side log entry

reset

A function that attempts to re-render the segment — useful when the error might be transient (e.g. a flaky network request)

Calling reset() doesn't reload the page. It simply tries to re-render the error boundary's children, which gives the user a lightweight "try again" experience instead of a full page refresh.
Errors are scoped to the segment
Placing error.tsx inside a specific route folder means only errors thrown within that segment — and its children — are caught there. An error thrown in app/dashboard/settings/ is caught by a error.tsx in that folder if one exists, or bubbles up to the nearest ancestor segment that has one. This lets you isolate a crash to a small part of the UI (say, a widget) while the rest of the page — navigation, sidebar, header — keeps working.

Folder structure

Text
app/
  dashboard/
    layout.tsx
    error.tsx        ← catches errors in page.tsx and settings/
    page.tsx
    settings/
      page.tsx
Note
An error.tsx file does not catch errors thrown in its own segment's layout.tsx — the error boundary wraps the layout's children, not the layout itself. To catch an error thrown inside a layout, the error.tsx needs to live one level up, in the parent segment.
Tip
Because error boundaries only catch errors during rendering, an error thrown inside a try/catch in an event handler won't reach error.tsx — you handle those manually (for example by setting local state to show a message).
  • error.tsx wraps a route segment in a React Error Boundary and must be a Client Component ('use client').

  • It receives error (the thrown Error, plus an optional digest) and reset (a function that re-renders the segment).

  • Errors bubble up to the nearest ancestor error.tsx if the segment where they occurred has none.

  • A layout's own errors are not caught by that layout's sibling error.tsx — only by one in a parent segment.