Vì error.tsx được render bên trong layout cùng cấp. Layout đã hỏng thì không thể bọc được UI lỗi của chính nó.
Cách xử lý:
- Lỗi ở app/dashboard/layout.tsx → cần app/error.tsx ở cấp cha bắt.
- Lỗi ở layout gốc (app/layout.tsx) hoặc template gốc → chỉ app/global-error.tsx bắt được. File này thay thế cả layout gốc nên phải tự render <html> và <body>.
tsx
// app/global-error.tsx
'use client'
export default function GlobalError({ error, reset }: { error: Error; reset: () => void }) {
return (
<html>
<body>
<h2>Something went wrong</h2>
<button onClick={reset}>Try again</button>
</body>
</html>
)
}Các điểm hay bị hỏi thêm:
- error.tsx bắt buộc là Client Component (cần state để reset).
- reset() render lại segment; nếu nguyên nhân chưa hết thì lỗi lặp lại.
- notFound() không đi vào error.tsx mà vào not-found.tsx.
- Ở production, message của lỗi server bị lược bỏ, chỉ còn error.digest để đối chiếu log.