首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Laravel 5.1 自定義 500 錯誤頁面:優雅處理致命錯誤與例外

     編輯:PHP 綜合知識

痛點:生產環境 500 錯誤顯示預設堆疊追蹤,體驗極差且洩露敏感資訊

Laravel 5.1 中,致命錯誤 (FatalErrorException) 會繞過常規例外處理,直接顯示預設錯誤頁。需在 App\Exceptions\Handler 中攔截並回應自定義視圖。

實作步驟

1. 修改 app/Exceptions/Handler.php

namespace App\Exceptions;

use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\Debug\Exception\FatalErrorException;

class Handler extends ExceptionHandler {
    public function render($request, Exception $e) {
        // ModelNotFound 轉 404
        if ($e instanceof \Illuminate\Database\Eloquent\ModelNotFoundException) {
            $e = new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException($e->getMessage(), $e);
        }

        // 關鍵:攔截生產環境致命錯誤,回應自定義視圖
        if ($e instanceof FatalErrorException && !config('app.debug')) {
            return response()->view('errors.default', [], 500);
        }

        return parent::render($request, $e);
    }
}

2. 建立自定義錯誤視圖 resources/views/errors/default.blade.php

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>系統錯誤 - 500</title>
    <style>
        body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; 
               display: flex; align-items: center; justify-content: center; min-height: 100vh; 
               margin: 0; background: #f5f5f5; }
        .card { background: white; padding: 3rem; border-radius: 8px; 
                box-shadow: 0 2px 10px rgba(0,0,0,0.1); text-align: center; max-width: 400px; }
        h1 { color: #e74c3c; margin-bottom: 1rem; }
        p { color: #666; line-height: 1.6; }
        a { color: #3498db; text-decoration: none; }
        a:hover { text-decoration: underline; }
    </style>
</head>
<body>
    <div class="card">
        <h1>😕 系統發生錯誤</h1>
        <p>我們已記錄此錯誤,技術團隊正在緊急處理中。</p>
        <p>請稍後重試,或 返回首頁。</p>
    </div>
</body>
</html>

進階:區分錯誤類型顯示不同頁面

public function render($request, Exception $e) {
    if (!config('app.debug')) {
        // 500 伺服器錯誤
        if ($e instanceof FatalErrorException || $e instanceof \ErrorException) {
            return response()->view('errors.500', [], 500);
        }
        // 404 找不到
        if ($e instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException) {
            return response()->view('errors.404', [], 404);
        }
        // 403 無權限
        if ($e instanceof \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException) {
            return response()->view('errors.403', [], 403);
        }
        // 419 CSRF 失效
        if ($e instanceof \Illuminate\Session\TokenMismatchException) {
            return response()->view('errors.419', [], 419);
        }
    }
    return parent::render($request, $e);
}

視圖檔案命名慣例 (Laravel 5.5+ 自動偵測)

resources/views/
└── errors/
    ├── 404.blade.php
    ├── 500.blade.php
    ├── 403.blade.php
    ├── 419.blade.php
    └── default.blade.php  (fallback)

Laravel 5.5+ 會自動根據 HTTP 狀態碼尋找對應視圖,無需手動 render() 判斷。

重要提醒

  • ⚠️ 生產環境必須關閉 APP_DEBUG=false,否則仍顯示詳細錯誤頁
  • 🔍 自定義錯誤頁**不應**包含複雜邏輯或資料庫查詢,避免錯誤頁本身再拋出錯誤
  • 📝 建議在自定義錯誤頁記錄 Log::error() 或整合 Sentry 等錯誤追蹤服務
  • 🎨 保持錯誤頁面簡潔、友善、品牌一致

測試驗證

# 臨時在路由觸發 500 測試
Route::get('test-500', function() {
    throw new \ErrorException('Test fatal error');
});

訪問 /test-500 應顯示自定義錯誤頁,而非預設堆疊追蹤。

三分鐘配置,讓生產環境錯誤頁從「工程師專用」變為「用戶友善」。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved