# Error boundary nell'App Router: cosa cattura error.tsx

error.tsx cattura gli errori del segmento sotto, non del layout che lo contiene. Gerarchia dei confini, global-error e il catch che inghiotte i redirect.

> Pagina: https://ui.eneawork.it/blog/nextjs-error-boundary-app-router
> Markdown: https://ui.eneawork.it/blog/nextjs-error-boundary-app-router.md

*2026-11-01*

In App Router `error.tsx` è un client component che cattura gli errori del segmento sotto di sé e mostra un fallback con un pulsante di reset. Non cattura gli errori del `layout` che lo contiene, né quelli del root layout.

## Dove va il file

app/ error.tsx # cattura gli errori sotto, non quelli del root layout global-error.tsx # ultimo confine: sostituisce html e body not-found.tsx dashboard/ error.tsx loading.tsx page.tsx

Il file è un confine React: Next.js avvolge il segmento in un error boundary e passa due props, `error` e `reset`. Deve avere `"use client"`, altrimenti la build lo rifiuta.

// app/dashboard/error.tsx "use client"; import { useEffect } from "react"; export default function DashboardError({ error, reset, }: { error: Error & { digest?: string }; reset: () => void; }) { useEffect(() => { console.error(error.digest ?? error.message); }, [error]); return ( Qualcosa è andato storto reset()}>Riprova ); }

`reset()` rirenderizza il segmento senza ricaricare la pagina. Serve quando l'errore è transitorio, per esempio una fetch fallita. Se la causa è un dato mancante, il retry produce lo stesso errore.

## La gerarchia dei confini

## Perché serve `global-error.tsx`

// app/global-error.tsx "use client"; export default function GlobalError({ reset }: { reset: () => void }) { return ( Errore imprevisto reset()}>Ricarica ); }

Il file globale sostituisce il root layout, quindi deve dichiarare `` e ``. È l'ultima rete: se non c'è, un errore nel root layout produce la pagina di errore del framework.

## Il caso che costa un pomeriggio

// app/bozza/[id]/page.tsx import { redirect } from "next/navigation"; export default async function Page(props: { params: Promise }) { const { id } = await props.params; try { const draft = await getDraft(id); if (!draft) redirect("/404"); // lancia un errore di controllo: mai dentro un try } catch { return null; // il redirect non arriva mai al router } }

`redirect()` e `notFound()` funzionano lanciando un errore speciale che il router intercetta. Un `try/catch` attorno a quella chiamata lo trasforma in un ritorno silenzioso: la pagina resta bianca e nessun log lo spiega.

## Il numero che conta

Il catalogo EneUI indicizza 111.985 componenti e 1.556 blocchi da 1.472 librerie, misurati il 1 novembre 2026 su `/api/stats`. Per il fallback servono error page, alert e error handling.

Un `error.tsx` per ogni area che deve fallire da sola. Un `global-error.tsx` per progetto. Il resto è un boundary in più da mantenere.

Un errore dentro uno slot segue le regole dello slot: vedi route parallele e slot. Per l'ordine di arrivo dei pezzi c'è streaming e Suspense. Per il 404 che compare dopo il deploy 404 dopo il deploy. Per il confronto tra framework Remix vs Next.js.

Limite noto: in produzione il messaggio degli errori server viene sostituito da un testo generico con un `digest`. Il dettaglio resta nei log del server, e senza quel digest non puoi collegare il fallback alla causa.

## FAQ

### `error.tsx` deve essere un client component?

Sì. Il boundary usa `useEffect` e `reset`, quindi richiede `"use client"`. Senza la direttiva la build fallisce con un errore esplicito.

### Perché il mio errore nel layout non viene catturato?

Perché un boundary non copre il proprio genitore. L'errore nel `layout.tsx` sale al `error.tsx` del livello superiore, e il root layout richiede `global-error.tsx`.

### A cosa serve `digest`?

A collegare il messaggio generico mostrato in produzione al log del server. Il testo dell'errore non esce dal server, il digest sì.

### `reset` ricarica la pagina?

No. Rirenderizza il segmento e ritenta il rendering. Per un reload completo devi chiamare `location.reload()` o usare un link.

### Gli errori negli event handler passano da `error.tsx`?

No. Un boundary React cattura solo errori di rendering. Un click che lancia un'eccezione richiede un `try/catch` nell'handler.
