Next.js Curriculum
MediumFile-System Conventions100% Free25 min read

Granular Error Handling with error.tsx and global-error.tsx

The 30-Second Interview Answer

error.tsx defines an isolated React Error Boundary around sibling page segments, allowing crashes to be caught without breaking the outer layout. It must be a Client Component and receives error and reset props. To catch errors in the root layout itself, Next.js requires global-error.tsx defining its own <html> and <body> tags.

Learning Objectives

Explain why error.tsx must always be a Client Component ("use client").

Implement error recovery mechanisms using the reset() function.

Understand why error.tsx cannot catch errors thrown inside its sibling layout.tsx.

Implement global-error.tsx to catch root layout crashes in production.

Prerequisites & Background Knowledge
React Error BoundariesApp Router component hierarchy

Why Interviewers Care

Critical for production resilience and enterprise fault tolerance questions in senior interview loops.

The Challenge

Why must error.tsx be a Client Component? Why can error.tsx NOT catch errors thrown in sibling layout.tsx files, and how does global-error.tsx solve root layout failures?

Code Architecture & Implementation

1// app/dashboard/error.tsx
2// MUST BE A CLIENT COMPONENT
3'use client';
4
5import { useEffect } from 'react';
6
7export default function DashboardError({
8 error,
9 reset,
10}: {
11 error: Error & { digest?: string };
12 reset: () => void;
13}) {
14 useEffect(() => {
15 // Log error to Sentry / Datadog
16 console.error('Captured dashboard error:', error);
17 }, [error]);
18
19 return (
20 <div className="error-card">
21 <h2>Failed to load analytics dashboard</h2>
22 <p>Error digest: {error.digest || 'Unknown'}</p>
23 {/* reset() re-renders the segment, attempting recovery */}
24 <button onClick={() => reset()}>Try Again</button>
25 </div>
26 );
27}
28
29// app/global-error.tsx
30// Catches errors in the ROOT layout. Must define <html> and <body>.
31'use client';
32
33export default function GlobalError({
34 error,
35 reset,
36}: {
37 error: Error & { digest?: string };
38 reset: () => void;
39}) {
40 return (
41 <html lang="en">
42 <body>
43 <div className="fatal-error-screen">
44 <h1>Critical System Error</h1>
45 <button onClick={() => reset()}>Restart Application</button>
46 </div>
47 </body>
48 </html>
49 );
50}

Architectural Explanation

Why error.tsx Must Be a Client Component

React Error Boundaries require the lifecycle methods componentDidCatch or getDerivedStateFromError, which only exist in client React. A Server Component cannot maintain client error boundary state.

The Layout-Error Scoping Rule

Look at the generated component tree:

jsx
<Layout>
  <ErrorBoundary fallback={<Error />}>
    <Page />
  </ErrorBoundary>
</Layout>

Notice that <ErrorBoundary> is rendered inside <Layout>:

  • An error thrown inside page.tsx is caught by error.tsx. The navigation layout remains functional!
  • An error thrown inside layout.tsx cannot be caught by its sibling error.tsx, because the error boundary is its child.
  • To catch an error in layout.tsx, you must place an error.tsx in the parent directory segment.

The Role of global-error.tsx

Because the root app/layout.tsx has no parent folder, a crash in the root layout cannot be caught by app/error.tsx.
Next.js provides app/global-error.tsx specifically for this failure mode:

  • It replaces the entire document on root crash.
  • It must define its own <html> and <body> tags.
  • It only triggers in production builds (in development, the Next.js error overlay displays instead).

Common Mistakes & Anti-Patterns

Omitting "use client" in error.tsx, causing a compile error.

Expecting app/error.tsx to catch errors thrown in app/layout.tsx.

Forgetting that global-error.tsx must provide <html> and <body> tags.

Interview Follow-Up Traps

Interviewer asks: "Does the error object in error.tsx contain full server stack traces in production?" Trap answer: Yes, for debugging. Correct answer: No! In production, Next.js strips sensitive stack traces and error messages for security, providing only a generic error and an error.digest hash to correlate with server logs.

Interviewer asks: "Does calling reset() perform a full browser reload?" Trap answer: Yes. Correct answer: No! reset() executes a soft client re-render of the error boundary segment.

Frequently Asked Questions

What is error.digest in Next.js?

digest is a unique hash generated by Next.js in production that matches the server-side error log with the client-side error boundary report.

Yes. Placing error.tsx at multiple folder levels allows granular fallbacks for sub-features while keeping the parent UI intact.

No. Not Found errors are handled specifically by not-found.tsx.

In local development, Next.js displays the rich Fast Refresh error overlay to aid debugging.

Yes. If a transient network blip caused the initial fetch to fail, calling reset() re-executes the server fetch.