[TOC]
# 錯誤
## 介紹
Laravel 錯誤及異常處理默認已配置好,`App\Exceptions\Handler`類負責記錄應用程序觸發的所有異常并呈現給用戶。
## 配置
`config/app.php`配置文件中的`debug`選項決定了對于一個錯誤實際上將顯示多少信息給用戶。默認情況下,該選項的設置將遵照存儲在`.env`文件中的`APP_DEBUG`環境變量的值。
對于本地開發,你應該將`APP_DEBUG`環境變量的值設置為`true`。在生產環境中,該值應始終為`false`。如果在生產中將該值設置為`true`,則可能會將敏感配置值暴露給應用程序的終端用戶。
## 異常處理器
### Report 方法
所有異常都是由`App\Exceptions\Handler`類處理的。這個類包含兩個方法:`report`和`render`。`report`方法用于記錄異常或將它們發送給如[Bugsnag](https://bugsnag.com/)或[Sentry](https://github.com/getsentry/sentry-laravel)等外部服務。默認情況下,`report`方法將異常傳遞給記錄異常的基類。
```
/**
* 報告或記錄異常
*
* 此處是發送異常給 Sentry、Bugsnag 等外部服務的好位置。
*
* @param \Exception $exception
* @return void
*/
public function report(Exception $exception)
{
if ($exception instanceof CustomException) {
//
}
parent::report($exception);
}
```
> 提示:不要在`report`方法中進行太多的`instanceof`檢查
#### 全局日志
在正常情況下, Laravel 會自動將當前用戶的 ID 作為數據添加到每一條異常日志中。 通過重寫`App\Exceptions\Handler`類中的`context`方法來定義全局環境變量。
```
/**
* 定義默認的環境變量
*
* @return array
*/
protected function context()
{
return array_merge(parent::context(), [
'foo' => 'bar',
]);
}
```
#### `report`輔助函數
有時你可能需要報告異常,但又不希望終止當前請求的處理。`report`輔助函數允許你使用異常處理器的`report`方法在不顯示錯誤頁面的情況下快速報告異常:
```
public function isValid($value)
{
try {
// 驗證值...
} catch (Exception $e) {
report($e);
return false;
}
}
```
#### 按類型忽略異常
異常處理器的`$dontReport`屬性包含一組不會被記錄的異常類型。例如,由 404 錯誤導致的異常以及其他幾種類型的錯誤不會寫入日志文件。你可以根據需要添加其他異常類型到此數組中:
```
/**
* 不應被報告的異常類型清單。
*
* @var array
*/
protected $dontReport = [
\Illuminate\Auth\AuthenticationException::class,
\Illuminate\Auth\Access\AuthorizationException::class,
\Symfony\Component\HttpKernel\Exception\HttpException::class,
\Illuminate\Database\Eloquent\ModelNotFoundException::class,
\Illuminate\Validation\ValidationException::class,
];
```
### Render 方法
`render`方法負責將給定的異常轉換為將被發送回瀏覽器的 HTTP 響應。默認情況下,異常將傳遞響應的基類。不過,可以按自己意愿檢查異常類型或返回自己的自定義響應:
```
/**
* 將異常轉換為 HTTP 響應。
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
if ($exception instanceof CustomException) {
return response()->view('errors.custom', [], 500);
}
return parent::render($request, $exception);
}
```
### Reportable & Renderable 異常
除了在異常處理器的`report`和`render`方法中檢查異常類型,你還可以直接在自定義異常上定義`report`和`render`方法。當定義了這些方法時,它們會被框架自動調用:
```
// 自定義異常類
<?php
namespace App\Exceptions;
use Exception;
class RenderException extends Exception
{
/**
* 報告異常
*
* @return void
*/
public function report()
{
//
}
/**
* 轉換異常為 HTTP 響應
*
* @param \Illuminate\Http\Request
* @return \Illuminate\Http\Response
*/
public function render($request)
{
return response(...);
}
}
```
> Tip:可以聲明`report`方法和必要參數,它們將通過 Laravel 的 [服務容器] 自動注入方法中。
## HTTP 異常
```
abort(404); // 頁面未找到
abort(403, 'Unauthorized action.');
```
### 自定義 HTTP 錯誤頁面
```
// 生成自定義錯誤模板頁面,生成目錄 resources/views/errors
$ php artisan vendor:publish --tag=laravel-errors
// 由 abort 函數拋出的 HttpException 實例將作為 $exception 變量傳遞給視圖
<h2>{{ $exception->getMessage() }}</h2>
```
- 入門指南
- 安裝
- 部署
- 基礎功能
- 路由
- 中間件
- CSRF 保護
- 控制器
- 請求
- 響應
- 視圖
- URL
- Session
- 表單驗證
- 錯誤
- 日志
- 前端開發
- Blade 模板
- 本地化
- 腳手架
- 編譯資源 Mix
- 安全相關
- 用戶認證
- API 認證
- 綜合話題
- 命令行
- 廣播
- 緩存
- 集合
- 事件
- 文件存儲
- 輔助函數
- 郵件發送
- 消息通知
- 擴展包開發
- 隊列
- 任務調度
- 數據庫
- 快速入門
- 查詢構造器
- 分頁
- 數據庫遷移
- 數據填充
- Redis
- Eloquent ORM
- 快速入門
- 速查表
- Artisan
- Auth
- Blade
- Cache
- Collection
- Composer
- Config
- Container
- Cookie
- DB
- Environment
- Event
- File
- Helper
- Input
- Lang
- Log
- Model
- Pagination
- Queue
- Redirect
- Request
- Response
- Route
- SSH
- Schema
- Security
- Session
- Storage
- String
- URL
- UnitTest
- Validation
- View