jenky/hades

Laravel应用的错误响应格式化器

2.2.0 2024-04-15 02:11 UTC

This package is auto-updated.

Last update: 2024-09-15 03:13:51 UTC


README

Latest Version on Packagist Github Actions Codecov Total Downloads Software License

在构建API时处理错误可能很痛苦。您无需手动构建错误响应,只需抛出异常,Hades会为您处理响应。

安装

您可以使用Composer将此包安装到您的Laravel项目中

$ composer require jenky/hades

安装Hades后,将特质HandlesExceptionResponse添加到您的app/Exceptions/Handler,Hades将自动捕获抛出的异常并将其转换为JSON表示形式。

<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Jenky\Hades\Exception\HandlesExceptionResponse;

class Handler extends ExceptionHandler
{
    use HandlesExceptionResponse;
}

配置

通用错误响应格式

默认情况下,所有抛出的异常都将转换为以下格式

{
    'message' => ':message', // The exception message
    'type' => ':type', // The exception type, default to exception class name
    'status_code' => ':status_code', // The corresponding HTTP status code, default to 500
    'errors' => ':errors', // The error bag, typically validation error messages
    'code' => ':code', // The exception code
    'debug' => ':debug', // The debug information
}

调试信息仅在应用不在production环境或debug模式开启时才可用。

示例

curl --location --request GET 'http://myapp.test/api/user' \
--header 'Accept: application/json'
{
  "message": "Unauthenticated.",
  "type": "AuthenticationException",
  "status_code": 401,
  "code": 0,
}

所有未用对应值替换的键都将从最终响应中删除。

如果您想为您的应用使用不同的错误格式,您应该在App\Providers\AppServiceProvider类的boot方法中调用Hades::errorFormat()方法。

use Jenky\Hades\Hades;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Hades::errorFormat([
        'message' => ':message',
        'error_description' => ':error',
    ]);
}

格式化异常响应

自定义异常响应

有时您无法控制异常的抛出方式,例如Laravel框架或其他第三方包的异常。Laravel 8引入了可渲染异常,但您需要手动构建响应,这可能会导致错误格式不一致。

Hades允许您注册自定义闭包来替换响应格式中的所有值。您可以通过app\Exceptions\Handlercatch方法来实现这一点,Laravel将通过检查闭包的类型提示来推断闭包渲染的异常类型。

use App\Exceptions\InvalidOrderException;

/**
 * Register the exception handling callbacks for the application.
 *
 * @return void
 */
public function register()
{
    $this->catch(function (InvalidOrderException $e) {
        $this->replace('type', 'order_exception')
            ->replace('code', 1001);
    });
}

Laravel 8之前,register方法在app\Exceptions\Handler中尚不可用。但是,您可以自己实现此方法。

use Illuminate\Contracts\Container\Container;

/**
 * {@inheritdoc}
 */
public function __construct(Container $container)
{
    parent::__construct($container);

    $this->register();
}

如果您不想修改异常处理器,您可以在服务提供程序中注册异常回调。通常,您应该从应用的App\Providers\AppServiceProvider类的boot方法中调用此方法。

use App\Exceptions\InvalidOrderException;
use Illuminate\Contracts\Debug\ExceptionHandler;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    $this->app[ExceptionHandler::class]->catch(function (InvalidOrderException $e, $handler) {
        $handler->replace('type', 'order_exception')
            ->replace('code', 1001);
    });
}

内容协商

强制JSON响应

默认情况下,Laravel期望请求包含带有MIME类型application/jsonAccept头或带有json格式的自定义MIME类型,如application/vnd.myapp.v1+json,以便返回JSON响应。否则,如果凭据无效或缺少/传递无效的授权令牌,您可能会被重定向到登录页面。

虽然这是一种良好的设计实践,但有时您可能希望自动将头附加到请求中,例如将Laravel用作纯API后端。为此,您应该在App\Providers\AppServiceProvider类的boot方法中调用Hades::forceJsonOutput()方法。

use Jenky\Hades\Hades;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Hades::forceJsonOutput();
}

Hades将为所有传入的API请求添加Accept: application/json头。如果您想使用自定义MIME类型,您可以使用withMimeType来指定MIME类型。

Hades::forceJsonOutput()
    ->withMimeType('application/vnd.myapp.v1+json');

识别API请求

为了强制响应返回JSON输出,Hades需要识别传入的请求,以便它不会在您的正常HTML页面上添加Accept头。

默认情况下,您在routes/api.php中定义的所有API路由都会自动应用/api URI前缀。Hades将检查传入请求的URI,并确定其URI与/api前缀匹配。

要自定义此行为,您可以传递闭包到Hades::forceJsonOutput(),以指导Hades如何识别传入的请求

use Illuminate\Http\Request;

Hades::forceJsonOutput(static function (Request $request) {
    return $request->is('api/v1/*');
});

变更日志

有关最近更改的更多信息,请参阅变更日志

测试

$ composer test

贡献

有关详细信息,请参阅贡献指南行为准则

安全

如果您发现任何与安全相关的问题,请发送电子邮件至contact@lynh.me,而不是使用问题跟踪器。

鸣谢

许可协议

MIT许可协议(MIT)。有关更多信息,请参阅许可文件