概觀
當你建立 Laravel 專案時,錯誤與例外處理已預先設定完成。 若要自訂,可透過bootstrap/app.php 的 withExceptions 方法。
例外處理流程
從發生例外到回應返回用戶端的流程如下:withExceptions 閉包的 $exceptions 物件是 Illuminate\Foundation\Configuration\Exceptions 實例,用來管理整個應用程式的例外處理。
除錯設定
config/app.php 的 debug 選項控制錯誤資訊的顯示程度。
預設會使用 .env 中 APP_DEBUG 環境變數的值。
例外的回報
例外的回報是指將例外記錄到日誌,或送到 Laravel Nightwatch、Sentry、Flare 等外部服務。 預設會依據config/logging.php 的設定寫入日誌。
自訂回報 callback
若想依例外種類做不同的回報處理,可透過report 方法傳入閉包。
Laravel 會依閉包的型別提示判斷例外種類。
stop() 或回傳 false。
report() 輔助函式
若只想回報例外但不顯示錯誤頁面,可使用 report() 輔助函式。
防止重複回報
同一個例外實例若被多次傳入report(),可能會造成日誌重複條目。
設定 dontReportDuplicates() 後,相同實例只會被記錄一次。
全域日誌脈絡
若想為所有例外日誌附加共同資訊,可使用context 方法。
若能取得目前使用者 ID 會自動加入。
為例外類別加上 context() 方法
在例外類別自身定義 context() 方法,可將該例外特有的脈絡資訊納入日誌。
變更日誌等級
若想以特定日誌等級記錄某類例外,可使用level 方法。
例外回報節流
若發生大量例外,可用throttle 方法限制回報量。
Limit。
例外的渲染
渲染是指將例外轉換為 HTTP 回應。 預設 Laravel 會自動產生合適的回應,但也可以自訂。自訂渲染 callback
透過render 方法傳入閉包將例外轉換為回應。
NotFoundHttpException)的渲染。
若閉包沒有回傳值,將使用預設的渲染。
自動判斷 JSON / HTML
Laravel 會依據請求的Accept 標頭自動判斷回傳 HTML 或 JSON。
若要自訂此判斷邏輯,可使用 shouldRenderJsonWhen。
完整覆寫回應
使用respond 方法可以對產生的回應再加工。
自訂例外類別
可在app/Exceptions/ 目錄下建立自訂例外類別。
若定義了 report() 或 render() 方法,Laravel 會自動呼叫,不必額外在 bootstrap/app.php 設定。
建立例外類別
1
建立例外類別
2
實作 report() 與 render()
report() 方法可透過型別提示注入依賴,Laravel 服務容器會自動解析。ShouldntReport 介面
對於不需要回報的例外,可實作 ShouldntReport 介面。
實作此介面的例外將不會被回報。
拋出例外
abort() 輔助函式
可在應用程式任何地方拋出 HTTP 錯誤回應。
abort_if() / abort_unless()
依條件拋出例外的輔助函式。
例外的全域控制
忽略特定例外
透過dontReport 指定不回報的例外。自訂渲染邏輯仍會執行。
dontReportWhen。
Laravel 預設會自動忽略部分例外,例如 404 錯誤、CSRF token 錯誤(419)、Origin 不一致(403)等。
啟用 Laravel 忽略中的例外
若想把預設被忽略的例外重新納入回報,使用stopIgnoring。
HTTP 錯誤頁面
Laravel 可為每個 HTTP 狀態碼定義自訂錯誤視圖。建立自訂錯誤視圖
在resources/views/errors/ 目錄建立以狀態碼為檔名的 Blade 樣板。
$exception 變數存取錯誤資訊。
發布預設錯誤樣板
若想以 Laravel 標準錯誤頁面為起點自訂,可透過vendor:publish 取得。
備援錯誤頁面
若沒有對應狀態碼的視圖,可作為備援建立4xx.blade.php 與 5xx.blade.php。
實戰範例:API 例外處理器
在提供 API 的應用程式中,例外通常都要以 JSON 回傳。 以下是在bootstrap/app.php 集中管理 API 錯誤的實作範例。
自訂 API 例外類別
建立 API 專屬的基底例外類別,可讓各端點都回傳一致的錯誤回應。總結
例外回報整理
例外回報整理
例外渲染整理
例外渲染整理
HTTP 錯誤頁面整理
HTTP 錯誤頁面整理
- 只需建立
resources/views/errors/404.blade.php等檔案即會自動使用 - 可透過
$exception變數存取錯誤詳情 - 執行
php artisan vendor:publish --tag=laravel-errors取得預設樣板 - 可以
4xx.blade.php/5xx.blade.php定義備援頁面
正式環境的最佳實踐
正式環境的最佳實踐
- 一定要設定
APP_DEBUG=false,避免讓使用者看到堆疊追蹤 - 與 Sentry、Flare 等外部錯誤追蹤服務整合,集中管理錯誤
- 使用
throttle()防止大量例外造成日誌爆量 - API 端點須維持一致的 JSON 錯誤回應格式