Next.js 13.4 App Router 的錯誤處理指南
本文將介紹如何在 Next.js 的 App Router 中使用新的錯誤文件約定來處理錯誤。
錯誤處理是任何 Web 應用程序開發的關鍵方面。過去,Next.js 通過自定義錯誤頁面(如 404 和 500 頁面)來幫助開發者處理錯誤。但是,這些頁面在 Pages Router 中存在局限性,例如對特定 UI 集成的支持有限、對 React 錯誤邊界支持過時以及發生錯誤時應用程序功能有限。
Next.js 13.4 版本發布後,新的 App Router 已正式投入生產使用。 App Router 增強了對錯誤處理和其他 Web 應用程序構建基本部分的支持和開發人員體驗。
app
目錄中的 error.tsx
文件創建了一個 React 錯誤邊界,防止應用程序在發生錯誤時崩潰。它還可以充當回退組件,在邊界內拋出錯誤時呈現。 AuthRequiredError
來處理各種路由中的身份驗證錯誤。 global-error.tsx
文件。如果錯誤發生在服務器組件中或在數據獲取期間,Next.js 將把相應的 Error 對象轉發到最近的 error.tsx
邊界。 為了便於理解新的錯誤處理 API,我們將探討它在 Next.js 用戶身份驗證應用程序中的實現。
用戶身份驗證容易出現許多錯誤,因此在構建其他應用程序時,學習如何在這種情況下去處理錯誤將對您大有裨益。
在開始之前,請通過克隆此處鏈接的倉庫(主分支)來獲取我們將在此文中使用的演示應用程序的代碼。運行應用程序後,您應該會看到下圖所示的錯誤。
在此演示應用程序中,主頁面(顯示表格)只能由已登錄的用戶訪問,但發生了一些錯誤(在這種情況下是人為製造的,但它也可能合法地發生),導致會話變量被賦值為null。
注意:為簡單起見,演示應用程序中不會實現身份驗證。
這當然會導致錯誤,現在,應用程序完全崩潰了,因為它不知道如何處理錯誤!
現在,我們將學習如何處理該錯誤以防止我們的應用程序崩潰,從而顯著提高應用程序的用戶體驗。
為了防止應用程序崩潰,在 app/
目錄中,創建一個 error.tsx
文件。創建此文件會自動創建一個 React 錯誤邊界,該邊界將包裝主頁面。然後,在 error.tsx
文件中,導出以下函數:
"use client"; export default function Error() { return ( <div className="grid h-screen px-4 bg-white place-content-center"> <div className="text-center"> <h1 className="font-black text-gray-200 text-9xl">401</h1> <p className="text-2xl font-bold tracking-tight text-gray-900 sm:text-4xl"> 未授权! </p> <p className="mt-4 text-gray-500"> 您必须登录才能访问此页面 </p> <button type="button" className="inline-block px-5 py-3 mt-6 text-sm font-medium text-white bg-indigo-600 rounded hover:bg-indigo-700 focus:outline-none focus:ring" > 重试 </button> </div> </div> ); }
注意:錯誤組件必須是客戶端組件!請務必將它們標記為客戶端組件。
導出的函數將充當回退組件。如果在邊界內拋出錯誤,則會捕獲該錯誤並呈現回退組件,該組件應如下所示。
發生錯誤時,會將兩個 props 傳遞給錯誤回退組件——錯誤對象本身以及嘗試從錯誤中恢復的函數(通常稱為 reset):
"use client"; type ErrorProps = { error: Error; reset: () => void; }; export default function Error({ error, reset }: ErrorProps) { // ... }
我們現在可以通過 error prop 訪問錯誤消息,並將其顯示在屏幕上,如下所示:
<p className="mt-4 text-gray-500"> {error.message || "您必须登录才能访问此页面"} </p>
當調用該函數時,reset 函數將嘗試重新渲染由錯誤邊界包圍的原始內容。如果成功,則回退錯誤組件將被重新渲染的內容替換。
我們可以使用 onClick 處理程序在我們的按鈕中實現 reset 函數調用:
<button type="button" onClick={() => reset()} className="inline-block px-5 py-3 mt-6 text-sm font-medium text-white bg-indigo-600 rounded hover:bg-indigo-700 focus:outline-none focus:ring cursor-pointer" > 重试 </button>
這樣,我們就成功地處理了我們的錯誤!
在一個實際的用戶身份驗證應用程序中,可能會有許多必須受保護的路由,如果發生身份驗證錯誤,則需要在多個實例中使用相同的身份驗證錯誤消息。
為了抽象錯誤消息(並且不重複編寫),我們可以輕鬆地創建一個與身份驗證相關的自定義異常。
為此,創建一個名為 lib
的目錄,並在該目錄中創建一個名為 exceptions.ts
的文件。在此文件中,我們可以創建和導出自定義身份驗證錯誤異常,如下所示:
export class AuthRequiredError extends Error { constructor(message = "需要身份验证才能访问此页面") { super(message); this.name = "AuthRequiredError"; } }
現在,我們可以在主頁面上拋出這個新的自定義 AuthRequiredError
,而不是常規的 Error
:
export default function Home() { if (!session) throw new AuthRequiredError(); // ... }
該錯誤將給我們提供構造函數中傳遞的默認消息,或者我們以後可能需要傳遞的更具體的錯誤。
最後,讓我們注意一下佈局和服務器錯誤的一些額外內容。
錯誤可能發生在應用程序的任何位置(不僅僅是 page.tsx
文件),Next.js 使用的文件路由系統會影響 error.tsx
邊界在嵌套路由和佈局中的工作方式。
錯誤會冒泡到最近的父錯誤邊界,這可以在下圖中看到。
這種錯誤冒泡的性質意味著 error.tsx
邊界不會捕獲同一部分中佈局文件中的錯誤,因為錯誤邊界會包裝佈局文件。
如果根佈局或模板中發生錯誤,請使用 global-error.tsx
文件,如下圖所示。
global-error.tsx
邊界會包裝整個應用程序,因此請確保在使用此文件時添加您自己獨特的 和
標籤。此錯誤邊界會捕獲其他嵌套
error.tsx
邊界未捕獲的任何錯誤,因此它不會經常被激活。
如果錯誤發生在服務器組件中或在數據獲取期間,Next.js 將把相應的 Error 對象轉發到最近的 error.tsx
邊界。
儘管許多開發人員認為實現錯誤處理很麻煩,但它是應用程序的重要組成部分,成功實現錯誤處理將顯著提高應用程序的用戶體驗。
借助 App Router 和 error.tsx
文件約定,Next.js 使此操作變得非常簡單。
您可以查閱 Next.js 關於錯誤處理的文檔,以了解有關錯誤處理的更多信息,您也可以在 GitHub 上查看本文的完成代碼。
(此處省略了FAQs 部分,因為原文的FAQs 部分與文章內容重複度較高,且部分問題與App Router 的錯誤處理機制關聯性較弱。如果需要,可以根據原文補充。)
以上是掌握Next.js錯誤處理應用程序路由器的詳細內容。更多資訊請關注PHP中文網其他相關文章!