错误处理
简介
当启动新的 Laravel 项目时,已经为您配置了错误和异常处理。App\Exceptions\Handler
类会记录应用触发的所有异常,然后渲染给用户。在该文档中,我们会深入讨论此类。
配置
config/app.php
配置文件中的 debug
选项决定了实际上会显示错误的多少内容给用户。默认情况下,该选项设置为跟随环境变量 APP_DEBUG
的值,它存储在 .env
文件中。
对于本地开发,应该将环境变量 APP_DEBUG
设置为 true
。在生产环境中,该值应始终设置为 false
。如果在生产中将该值设置为 true
,会有将敏感配置信息暴露给应用终端用户的风险。
异常处理器
report 方法
所有异常都由 App\Exceptions\Handler
类处理。该类包含两个方法:report
和 render
。我们会详细研究每个方法。report
方法用于记录异常或者将其发送给外部服务,如 Bugsnag 或 Sentry。默认情况下,report
方法会将异常传递给记录异常的基类。不过,您可以根据需要自由记录异常。
例如,如果要用不同的方式报告不同类型的异常,可以使用 PHP 的类型运算符 instanceof
:
/**
* 报告或记录异常
*
* 这里是一个将异常发送给 Sentry,Bugsnag 等的好地方
*
* @param \Exception $exception
* @return void
*/
public function report(Exception $exception)
{
if ($exception instanceof CustomException) {
//
}
return parent::report($exception);
}
不要在
report
方法中进行大量的instanceof
检查,而应考虑使用 reportable 异常。
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
方法。当这些方法存在时,框架会自动调用它们:
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(...);
}
}
HTTP 异常
一些异常描述了服务器的 HTTP 错误码。例如,可能是「未找到页面」(404),「未授权错误」(401)或者甚至是开发者生成的 500 错误。可以使用 abort
辅助函数在应用的任何位置生成类似响应:
abort(404);
abort
辅助函数会立即抛出异常处理器生成的异常。还可以提供可选的响应文本:
abort(403, 'Unauthorized action.');
自定义 HTTP 错误页面
Laravel 可以轻松显示各种 HTTP 状态码的自定义错误页面。例如,如果要为 404 HTTP 状态码自定义错误页面,创建一个 resources/views/errors/404.blade.php
。应用生成的所有 404 错误都会显示该文件。该目录下的视图命名应该和对应的 HTTP 状态码相匹配。abort
函数抛出的 HttpException
实例会作为 $exception
变量传递到视图:
<h2>{{ $exception->getMessage() }}</h2>