1. 程式人生 > >Laravel 5.1 中的異常處理器和HTTP異常處理 abort()

Laravel 5.1 中的異常處理器和HTTP異常處理 abort()

錯誤日誌 exce ant upload 記錄 再次 .org splay don

原文 http://laravelacademy.org/post/1867.html

錯誤和異常是處理程序開發中不可回避的議題,在本地開發中我們往往希望能捕獲程序拋出的異常並將其顯示打印出來,以便直觀的知道程序在哪裏出了問題並予以解決,而在線上環境我們不希望將程序錯誤或異常顯示在瀏覽器中(出於安全考慮),這個時候我們仍然要捕獲異常,只不過不是顯示到瀏覽器中,而是記錄到日誌中,方便日後排查問題。

Laravel當然支持PHP原生的錯誤和異常處理,但是在此基礎上進行了一些封裝處理,從而更方便在不同開發環境切換以及對錯誤和異常的處理。

1、配置

我們可以在config/app.php文件中通過debug配置項來決定是否開啟調試模式,其默認配置如下:

‘debug‘ => env(‘APP_DEBUG‘, false),

當然真正的配置位於項目根目錄下的.env文件,如果其值為true,則如果程序拋出異常會在頁面中顯示錯誤異常信息。

2、異常處理器

Laravel應用中所有的異常都通過App\Exceptions\Handler進行處理,下面我們先簡單分析下給異常處理器類的屬性和方法:

$dontReport屬性

protected $dontReport = [
    HttpException::class,
    ModelNotFoundException::class,
];

$dontReport屬性定義了不會被記錄到日誌的異常,比如默認HTTP異常和ModelNotFound

異常都不會記錄下來,而是直接在瀏覽器中打印異常信息。

report方法

public function report(Exception $e)
{
    return parent::report($e);
}

report方法會調用父級的report方法將異常信息記錄到日誌中(關於日誌我們將在下一節講)。

render方法

public function render($request, Exception $e)
{
    if ($e instanceof ModelNotFoundException) {
        $e = new NotFoundHttpException($e->getMessage(), $e);
    }

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

render方法會將異常信息渲染到HTTP響應中,從而讓我們在開發過程中直觀地瀏覽器中查看錯誤信息以便找到問題所在。

簡單測試示例

下面我們來簡單測試下ModelNotFoundException,顧名思義,在使用Eloquent ORM進行查詢時對應模型實例在數據庫中沒有找到會拋出該異常。

我們照例在TestController的index方法中編寫測試代碼如下:

$user = User::findOrFail(100);
dd($user);

然後在瀏覽器中訪問http://laravel.app:8000/test,頁面會打印出錯誤信息:

技術分享

由於ModelNotFoundException$dontReport屬性數組中,因而不會記錄到日誌中(NotFoundHttpExceptionHttpException的子類,所以也不會被記錄到日誌),接下來我們測試如下代碼:

$num = 1/0;

再次訪問http://laravel.app:8000/test,同樣,頁面會打印錯誤信息:

技術分享

除此之外,在錯誤日誌storage/logs/laravel.log中也能看到寫入進來的錯誤信息:

[2015-11-08 21:21:47] local.ERROR: exception ‘ErrorException‘ with message ‘Division by zero‘ in /vagrant/laravelapp/app/Http/Controllers/TestController.php:389
Stack trace:
...

而且,通過這些錯誤信息,既可以知道出錯原因,也知道出錯代碼在程序中的位置,可以大大節省我們排查錯誤原因的時間,提高編程效率。

3、HTTP異常處理

日常開發中,我們經常會遇到404、500之類的HTTP錯誤碼,表示頁面未找到或者服務器錯誤之類的問題,Laravel為我們提供了單獨的方法來處理這些錯誤異常:

abort方法

我們使用abort方法來簡單拋出HTTP錯誤碼異常,如果頁面沒找到或者數據不存在,我們使用如下方法拋出404異常:

abort(404);

如果是服務器授權認證失敗,我們可以通過如下方式拋出403異常,當然,還可以傳入錯誤信息到abort方法:

abort(403,‘對不起,您無權訪問該頁面!‘);

對於拋出403異常的頁面,默認顯示如下:

技術分享

這樣的頁面顯然不能放到線上環境,那又應該如何為HTTP異常創建自定義視圖呢?別擔心,Laravel已經為我們做了周全的處理:

錯誤頁面視圖

如果要創建諸如404、403、500這樣的HTTP異常自定義視圖,只需在resources/views/errors目錄創建與錯誤碼對應的頁面視圖文件即可。比如要定義上述403異常自定義視圖,可以創建resources/views/errors/403.blade.php文件,現在我們簡單定義其內容如下:

{{$exception->getMessage()}}

這樣再次測試403異常頁面,顯示如下:

對不起,您無權訪問該頁面!

沒錯,就是403.blade.php文件中的內容,是不是很方便?

註:abort方法底層還是拋出相應異常,404錯誤拋出NotFoundHttpException,其他HTTP錯誤拋出HttpException

Laravel 5.1 中的異常處理器和HTTP異常處理 abort()