Handling expected errors
Expected errors should be modeled as return values, not thrown exceptions.Server Functions
Use theuseActionState hook to handle expected errors from Server Functions. Instead of throwing, return the error as a value:
useActionState to read the returned state and display the error:
Server Components
In a Server Component, use the fetch response to conditionally render an error message:Not found
CallnotFound() to render a 404 UI. Create a not-found.tsx file in the route segment to customize the UI:
Handling uncaught exceptions
Unexpected errors should be thrown. Next.js catches them with error boundaries and displays fallback UI.The error.js convention
Create an error.tsx file inside a route segment to define an error boundary for that segment:
error.tsx files at different levels in the route hierarchy to control the scope of error recovery.
Component hierarchy with error boundary:
The
error.tsx component must be a Client Component because it uses React lifecycle methods to catch and display errors during rendering.Custom error boundaries with unstable_catchError
For component-level error recovery, use unstable_catchError to create error boundaries that wrap any part of your component tree:
Global errors
Handle errors in the root layout usingglobal-error.tsx. This replaces the root layout when active, so it must include <html> and <body> tags:
Errors in event handlers
Error boundaries don’t catch errors inside event handlers — they only catch errors during rendering. For event handler errors, usetry/catch with useState:
Errors in transitions
Unhandled errors insidestartTransition from useTransition bubble up to the nearest error boundary:
Summary
Expected errors
Return errors as values from Server Functions. Use
useActionState in Client Components to display them. Use notFound() for 404s.Unexpected errors
Throw errors and let error boundaries catch them. Use
error.tsx for route-level boundaries, global-error.tsx for the root layout.