简介
当你安装一个新的 Laravel 应用时,错误与异常处理已经为你配置好了。应用所有的异常都会触发 App\Exceptions\Handler
类,记录并渲染后返回给用户。该文档将会深入探讨这个类。
日志方面,Laravel 使用 Monolog 类库,它提供了多种强大的日志处理功能。Laravel 为你配置好了其中的几个处理器,允许你在使用单个日志文件、分隔日志文件、或者把错误信息写入到系统日志等方法中进行选择。
配置
错误详情
config/app.php
配置文件中的 debug
选项会确定一个错误到底会展示多少信息给用户。默认情况下,这个选项的值是由位于 .env
文件中环境变量 APP_DEBUG
来设置。
本地开发环境中,你需要把 APP_DEBUG
设置为 true
。而在生产环境,这个值将永远为 false
。如果这个值在生产环境被设置为 true
,应用中敏感的配置值暴露给终端用户的风险将大大提升。
日志存储
默认情况下,Laravel 提供把日志信息写入到 single
文件、daily
文件、syslog
以及 errorlog
等四种方式,要配置 Laravel 使用哪种机制进行存储,你需要修改 config/app.php
文件中的 log
选项。例如,你希望使用每天一个日志文件而非单个日志文件,你需要把 app
配置文件中的 log
值设置为 daily
:
'log' => 'daily'
日志文件最大天数
当使用 daily
模式时,Laravel 默认只会保留最近五天的日志文件。如果你想要调整保留日志文件的数量,可以添加 log_max_files
配置项到你的 app
配置文件:
'log_max_files' => 30
日志严重级别
当使用 Monolog 时,日志信息会有不同的错误级别,默认情况下,Laravel 会把所有日志都记录下来。然而,在生产环境中,你可以通过在 app.php
配置文件中添加 log_level
配置项来设置需要记录的日志的严重级别。
当配置这个值后,Laravel 只会记录所有大于等于这个级别的日志。例如,log_level
设置为 error
后将会记录 error、critical、alert、emergency 级别的日志:
'log_level' => env('APP_LOG_LEVEL', 'error'),
自定义 Monolog 配置
如果你想完全控制应用的 Monolog 的配置,你可能需要 configureMonologUsing
方法。你需要在 bootstrap/app.php
文件返回 $app
变量前调用该方法:
$app->configureMonologUsing(function($monolog) { $monolog->pushHandler(...); }); return $app;
异常处理器
Report 方法
所有异常都是由 App\Exceptions\Handler
处理的。这个类包含了两个方法:report
和 render
。下面我们详细讲述这两个方法。report
方法是用来记录异常或是将它们发送给外部服务,如 BugSnag 或 Sentry。默认情况下,report
只是将异常传递给基类,在那里异常将被记录。然而,你可以根据自己的喜好来记录它们。
例如,你想要用不同的方式报告不同的异常,你可以使用 PHP 的 instanceof
比较操作符:
/** * Report or log an exception. * * This is a great spot to send exceptions to Sentry, Bugsnag, etc. * * @param \Exception $e * @return void */ public function report(Exception $e) { if ($e instanceof CustomException) { // } return parent::report($e); }
根据类型忽略异常
异常处理器的 $dontReport
包含了一个将不会被记录的异常类型的数组。例如,404
结果的异常,以及几个其他类型的异常将不会被记录到日志文件。你可以根据需要添加其他异常类型到这个数组:
/** * A list of the exception types that should not be reported. * * @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 请求的。默认情况下,异常被传递给基类并为你生成一个响应。然而,你可以检查异常类型或返回自定义的响应:
/** * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request * @param \Exception $e * @return \Illuminate\Http\Response */ public function render($request, Exception $e) { if ($e instanceof CustomException) { return response()->view('errors.custom', [], 500); } return parent::render($request, $e); }
HTTP 异常
有一些异常是用于描述来自服务器的 HTTP 错误码。例如,可能是一个“页面未找到”的错误(404
),“未授权错误”(401
)甚至是开发者造成的 500
错误。想在应用的任何位置生成这样的响应,你可以使用 abort
辅助方法:
abort(404);
abort
方法会立刻抛出一个会被异常处理器渲染的异常,此外还为你提供了一个自定义响应文本的选项:
abort(403, 'Unauthorized action.');
自定义 HTTP 错误页
Laravel 使得自定义多种 HTTP 状态码的错误页变得更加简单。例如你想自定义一个 404
状态码的错误页面,只需创建一个 resources/views/errors/404.blade.php
文件。应用产生的所有 404
错误都将有这个页面展示。位于这个文件夹下的视图文件都需要与它们返回的 HTTP 状态码相匹配。abort
方法产生的 HttpException
实例都将作为 $exception
变量传递给视图。
日志
Laravel 在强大的 Monolog 类库基础上提供了一个简单的抽象层。默认情况下,Laravel 将在 storage/logs
目录下为你的应用创建日志文件。你可以使用 Log
Facade 向其中写信息:
<?php namespace App\Http\Controllers; use App\User; use Illuminate\Support\Facades\Log; use App\Http\Controllers\Controller; class UserController extends Controller { /** * Show the profile for the given user. * * @param int $id * @return Response */ public function showProfile($id) { Log::info('Showing user profile for user: '.$id); return view('user.profile', ['user' => User::findOrFail($id)]); } }
日志记录器提供了 RFC 5424 中定义的八种日志级别:emergency、alert、critical、error、warning、notice、info、debug。
Log::emergency($message); Log::alert($message); Log::critical($message); Log::error($message); Log::warning($message); Log::notice($message); Log::info($message); Log::debug($message);
上下文信息
你也可以传递一个上下文数据数组给日志方法。此上下文的相关数据会被格式化并与日志消息一同展示:
Log::info('User failed to login.', ['id' => $user->id]);
访问底层 Monolog 底层实例
Mongolog 还提供了一些额外的你可能需要使用的异常处理器。如果需要,你可以访问 Laravel 使用的底层的 Mongolog 实例:
$monolog = Log::getMonolog();
该篇属于专题:《Laravel 5.3 中文文档》