Error handling
If an exception is thrown while a page renders — the database is down, an external API returned an error — Next.js by default shows a blank page with a failure message. An error.tsx file replaces it with your own page with a clear text and a "Try again" button.
The error.tsx file
Create app/posts/error.tsx. It must be a client component — the retry button works in the browser:
// app/posts/error.tsx
'use client';
export default function PostsError({ error, retry }: { error: Error; retry: () => void }) {
return (
<div>
<h2>Could not load posts</h2>
<p>{error.message}</p>
<button onClick={() => retry()}>Try again</button>
</div>
);
}Next.js passes the component the error object and a retry function that fetches the data again and tries to render the page. Articles about Next.js 15 use reset instead: it still exists but only clears the error without refetching data.
Trying it
Temporarily throw an error in getPosts in lib/posts.ts:
// lib/posts.ts (temporary)
export async function getPosts(): Promise<Post[]> {
throw new Error('The database is unavailable');
}Open /posts: instead of the list, "Could not load posts" appears, and the header and menu from the layouts stay in place. Put the function code back afterwards.
Where error.tsx applies
The file catches errors of the pages in its folder and all nested ones — /posts, /posts/hello-nextjs. It does not catch the layout of the same folder: an error in app/posts/layout.tsx is handled by the error.tsx one level up. Errors in the root layout are caught by a separate app/global-error.tsx file; it replaces the whole page, so it contains the html and body tags itself.
| File | What it catches |
|---|---|
app/posts/error.tsx | Pages of the /posts section |
app/error.tsx | All pages of the site |
app/global-error.tsx | Errors in the root layout |
The message in production
In the built site, error texts from server components are hidden: error.message holds a generic phrase, and the object has a digest field — a code to find the error in the server logs. This way the visitor does not see internal details such as the database path.
Expected errors
Not every error is an exception. A badly filled form or a post address that is already taken are expected situations. In server actions such errors are returned as values, as in the form validation lesson, and shown next to the field. error.tsx is for real failures.
Common mistake
Forgetting 'use client' on the first line of error.tsx. Next.js reports right away that an error file must be a client component. Remember: error.tsx and global-error.tsx are always client components, while not-found.tsx and loading.tsx can be server components.