錯誤處理
error.js
檔案約定讓您能優雅地處理嵌套路由中的意外運行時錯誤。
- 自動將路由區段及其嵌套子項目包裹在 React 錯誤邊界中
- 利用檔案系統層級結構來調整粒度,為特定區段建立專屬的錯誤 UI
- 將錯誤隔離在受影響的區段,同時保持應用程式其餘部分正常運作
- 添加功能以嘗試從錯誤中恢復,無需完整頁面重新載入
透過在路由區段內添加 error.js
檔案並導出 React 組件來建立錯誤 UI:

'use client' // 錯誤組件必須是客戶端組件
import { useEffect } from 'react'
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string }
reset: () => void
}) {
useEffect(() => {
// 將錯誤記錄到錯誤報告服務
console.error(error)
}, [error])
return (
<div>
<h2>發生錯誤!</h2>
<button
onClick={
// 嘗試透過重新渲染區段來恢復
() => reset()
}
>
重試
</button>
</div>
)
}
'use client' // 錯誤組件必須是客戶端組件
import { useEffect } from 'react'
export default function Error({ error, reset }) {
useEffect(() => {
// 將錯誤記錄到錯誤報告服務
console.error(error)
}, [error])
return (
<div>
<h2>發生錯誤!</h2>
<button
onClick={
// 嘗試透過重新渲染區段來恢復
() => reset()
}
>
重試
</button>
</div>
)
}
error.js
運作原理

error.js
會自動建立一個 React 錯誤邊界,包裹嵌套的子區段或page.js
組件- 從
error.js
檔案導出的 React 組件將作為後備組件使用 - 如果在錯誤邊界內拋出錯誤,錯誤會被封裝,並渲染後備組件
- 當後備錯誤組件處於活動狀態時,錯誤邊界上方的布局會保持其狀態並維持可互動性,且錯誤組件可以顯示從錯誤中恢復的功能
從錯誤中恢復
有時錯誤的原因可能是暫時性的。在這些情況下,只需重試可能就能解決問題。
錯誤組件可以使用 reset()
函數提示用戶嘗試從錯誤中恢復。執行時,該函數會嘗試重新渲染錯誤邊界的內容。如果成功,後備錯誤組件將被重新渲染的結果取代。
'use client'
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string }
reset: () => void
}) {
return (
<div>
<h2>發生錯誤!</h2>
<button onClick={() => reset()}>重試</button>
</div>
)
}
'use client'
export default function Error({ error, reset }) {
return (
<div>
<h2>發生錯誤!</h2>
<button onClick={() => reset()}>重試</button>
</div>
)
}
嵌套路由
透過特殊檔案建立的 React 組件會在特定的嵌套層級結構中渲染。
例如,包含 layout.js
和 error.js
檔案的兩個嵌套區段會以下列簡化的組件層級結構渲染:

嵌套組件層級結構會影響嵌套路由中 error.js
檔案的行為:
- 錯誤會冒泡到最近的父級錯誤邊界。這意味著
error.js
檔案將處理其所有嵌套子區段的錯誤。透過在路由的嵌套資料夾不同層級放置error.js
檔案,可以實現更細緻或更粗略的錯誤 UI。 error.js
邊界不會處理在同一區段的layout.js
組件中拋出的錯誤,因為錯誤邊界嵌套在該布局組件內部。
處理布局中的錯誤
error.js
邊界不會捕獲同一區段的 layout.js
或 template.js
組件中拋出的錯誤。這種刻意設計的層級結構能在錯誤發生時,保持兄弟路由之間共享的重要 UI(如導航)可見且可運作。
要處理特定布局或模板內的錯誤,請在布局的父級區段放置 error.js
檔案。
要處理根布局或模板中的錯誤,請使用 error.js
的變體 global-error.js
。
處理根布局中的錯誤
根目錄的 app/error.js
邊界不會捕獲根 app/layout.js
或 app/template.js
組件中拋出的錯誤。
要專門處理這些根組件中的錯誤,請在根 app
目錄使用 error.js
的變體 app/global-error.js
。
與根 error.js
不同,global-error.js
錯誤邊界會包裹整個應用程式,其後備組件在活動時會取代根布局。因此請注意,global-error.js
必須定義自己的 <html>
和 <body>
標籤。
global-error.js
是最不精細的錯誤 UI,可視為整個應用程式的「全局捕獲」錯誤處理。由於根組件通常較少動態變化,且其他 error.js
邊界會捕獲大多數錯誤,因此它不太常被觸發。
即使定義了 global-error.js
,仍建議定義根 error.js
,其後備組件將在根布局內部渲染,包含全局共享的 UI 和品牌標識。
'use client'
export default function GlobalError({
error,
reset,
}: {
error: Error & { digest?: string }
reset: () => void
}) {
return (
<html>
<body>
<h2>發生錯誤!</h2>
<button onClick={() => reset()}>重試</button>
</body>
</html>
)
}
'use client'
export default function GlobalError({ error, reset }) {
return (
<html>
<body>
<h2>發生錯誤!</h2>
<button onClick={() => reset()}>重試</button>
</body>
</html>
)
}
處理伺服器錯誤
如果在伺服器組件中拋出錯誤,Next.js 會將 Error
物件(在生產環境中會移除敏感錯誤資訊)作為 error
屬性傳遞給最近的 error.js
檔案。
保護敏感錯誤資訊
在生產環境中,傳遞給客戶端的 Error
物件僅包含通用的 message
和 digest
屬性。
這是一種安全預防措施,避免將錯誤中包含的潛在敏感細節洩露給客戶端。
message
屬性包含關於錯誤的通用訊息,digest
屬性包含自動生成的錯誤哈希值,可用於匹配伺服器端日誌中的相應錯誤。
在開發環境中,傳遞給客戶端的 Error
物件會被序列化,並包含原始錯誤的 message
以便於除錯。