elle-the-dev / glove
Laravel 的异常处理,像手套一样抓取。
Requires
- php: 7.*|8.*
- illuminate/contracts: 8.*|9.*
- illuminate/support: 8.*|9.*
- psr/log: ^1.0
- symfony/console: 5.*|6.*
- symfony/debug: ^3.1|4.*
- symfony/http-foundation: 5.*|6.*
Requires (Dev)
- filp/whoops: 2.*
- mockery/mockery: ^1.0
- orchestra/testbench: 7.*
- phpunit/phpunit: 9.*
README
使用 Laravel Glove 捕获异常。本包的主要目标是尽可能简化添加自定义错误页面和创建自定义错误处理器的过程,以便我们完成所需的功能。
这意味着
需求
Laravel Glove 为 Laravel 5.5 及更高版本编写,因此还要求 PHP 7.0 及更高版本。
安装
安装通过 composer 完成
composer require ellehamilton/glove
安装完成后,我们需要运行
php artisan vendor:publish
如果我们不使用自动发现,我们需要将 GloveServiceProvider
添加到 config/app.php
中的 providers 数组中
ElleTheDev\Glove\Providers\GloveServiceProvider::class,
Glove 自动与 Whoops 集成,无需额外配置。
错误页面
我们可以通过更新 config/glove-codes.php
来轻松自定义错误页面
基本示例
让我们将所有 404 状态码发送到我们的 errors.404
视图。
... 404 => [ 'view' => [ 'http' => 'errors.404', 'ajax' => 'vendor.glove.ajax.exception' ] ] ...
带数据的错误页面
可以通过传递额外的数据到我们的视图来协助多次状态码的重用视图。
... 404 => [ 'view' => [ 'http' => 'errors.404', 'ajax' => 'vendor.glove.ajax.exception' ], 'data' => [ 'foo' => 'bar' ] ] ...
如果我们想让我们的视图在调试设置中显示为一个页面,我们可以将调试覆盖设置为 false,这样,例如,404 页面总是以这样的方式出现,而不是显示 Whoops 调试页面。
... 404 => [ 'view' => [ 'http' => 'errors.404', 'ajax' => 'vendor.glove.ajax.exception' ], 'debug' => false ] ...
debug
在不存在时默认为 true
。
通过更改 ajax
视图,我们可以使用我们自己的自定义 AJAX 格式。默认情况下,提供的视图将产生以下格式
{ error: { code: 404, message: "404 Page Not Found. The address you were looking for does not exist." } }
HTTP 状态码
我们可以在 config/glove.php
中指定哪个异常抛出哪个状态码
让我们让 MyException
抛出 403
状态码
'statusCodes' => [ ... \App\Exceptions\MyException::class => 403, ... ]
状态码按顺序从上到下解释。第一个找到的抛出异常的异常实例将用作状态码。
例如,如果我们有以下内容
'statusCodes' => [ \App\Exceptions\MyException::class => 403, \Exception::class => 500, ];
如果我们抛出 \App\Exceptions\MyException
,状态码将是 403
,因为它匹配并且是最先的。如果我们反转顺序
'statusCodes' => [ \Exception::class => 500, \App\Exceptions\MyException::class => 403, ];
那么状态码将是 500
,因为 \App\Exceptions\MyException
是 Exception
的实例,并且首先匹配。
\Symfony\Component\HttpKernel\Exception\HttpException
是一个特殊情况。当使用 abort(403)
或其变体时(不包括 404
状态码的情况),将产生包含状态码的 HttpException
。Glove 会自动处理这种情况,并将 HttpException
解释为它包含的状态码,因此除非我们希望覆盖其处理,否则无需将其包含在状态码配置中。
日志记录
是否记录异常以及记录它们的日志级别,可以在config/glove.php
中进行指定。
记录按照从上到下的顺序考虑,与状态码的处理方式相同。
跳过记录
我们可以通过将日志级别设置为ignore
来忽略异常的记录。
'logLevels' => [ ... \App\Exceptions\MyException::class => 'ignore', ... ]
更改日志级别
我们可以将日志级别从默认的'error'更改为Laravel的任何日志级别。
'logLevels' => [ \App\Exceptions\MyException::class => 'critical' ]
自定义异常处理
编写自定义异常处理器的简单方法是实现\ElleTheDev\Glove\Contracts\Handler
接口,然后在config/glove.php
中指定何时运行。
只需实现一个函数。
public function handle(\Illuminate\Http\Request $request, \Exception $e);
自定义响应
要返回自定义响应,从handle
方法中返回一个响应。
假设我们有一个自定义异常,MyException
namespace App\Exceptions; class MyException extends \Exception { }
我们将编写一个自定义处理器来处理该异常。
namespace App\Exceptions\Handlers; use ElleTheDev\Glove\Contracts\Handler; use Illuminate\Http\Request; use Exception; class MyHandler implements Handler { public function handle(Request $request, Exception $e) { return response(json_encode(['foo' => 'bar'])) ->header('Content-Type', 'application/json'); } }
一旦MyHandler
存在,我们就可以将其添加到config/glove.php
中。
如果我们只想在它是AJAX请求时运行,我们可以将其添加到handlers
的ajax
部分。
'handlers' => [ ... 'ajax' => [ ... \App\Exceptions\MyException::class => [ \App\Exceptions\Handlers\MyHandler::class ], ... ] ... ],
异常可以具有多个处理器,就像返回的是null
而不是响应对象一样,它将级联并继续处理处理器,直到接收到响应。
处理器按照从上到下的顺序解释,与状态码的处理方式相同。
无响应的自定义处理器
如果我们想让我们的处理器做些事情,但又想让其他处理器处理如何响应,我们可以简单地省略返回值或返回null以进行级联。
namespace App\Exceptions\Handlers; use ElleTheDev\Glove\Contracts\Handler; class MyHandler implements Handler { public function handle(Request $request, Exception $e) { \Log::info("Something happened!"); } }