mixerapi/exception-render

处理API中的实体验证错误和其他异常的渲染

安装次数: 51,177

依赖关系: 1

建议者: 0

安全: 0

星标: 0

关注者: 2

分支: 1

类型:cakephp-plugin

v2.0.3 2024-02-17 22:15 UTC

README

Latest Version on Packagist Build Coverage Status MixerApi CakePHP Minimum PHP Version

此插件处理API中的实体验证错误和其他异常的渲染。

  • add()edit()操作上的Validator集成。
  • 将抛出的异常的短名称添加到响应中

更多信息请访问MixerAPI.com

安装

!!!提示 "" 如果您已安装MixerApi,则可以跳过此步骤。

composer require mixerapi/exception-render
bin/cake plugin load MixerApi/ExceptionRender

或者,在composer安装后,您可以手动在您的应用程序中加载此插件

# src/Application.php
public function bootstrap(): void
{
    // other logic...
    $this->addPlugin('MixerApi/ExceptionRender');
}

设置

在您的config/app.php文件中,更改默认的exceptionRenderer

'Error' => [
    'errorLevel' => E_ALL,
    'exceptionRenderer' => MixerApi\ExceptionRender\MixerApiExceptionRenderer::class,
    'skipLog' => [],
    'log' => true,
    'trace' => true,
],

用法

在您的表类中,像平常一样定义验证,然后通过在afterMarshall事件上附加监听器,由MixerApiExceptionRenderer处理其余部分,该事件在调用patchEntity()或newEntity()时将请求数据合并到实体中触发。如果验证失败,则抛出ValidationException并使用HTTP 422状态码进行渲染。

示例控制器操作

public function add()
{
    $this->request->allowMethod('post');
    $actor = $this->Actors->newEmptyEntity();
    $actor = $this->Actors->patchEntity($actor, $this->request->getData()); // potential ValidationException here
    if ($this->Actors->save($actor)) {
        $this->viewBuilder()->setOption('serialize', 'actor');
        $this->set('actor', $actor);

        return;
    }
    throw new \Exception("Record failed to save");
}

输出

{
  "exception": "ValidationException",
  "message": "Error saving resource `Actor`",
  "url": "/actors",
  "code": 422,
  "violations": [
    {
      "propertyPath": "first_name",
      "messages": [
        {
          "rule": "_required",
          "message": "This field is required"
        }
      ]
    },
    {
      "propertyPath": "last_name",
      "messages": [
        {
          "rule": "_required",
          "message": "This field is required"
        }
      ]
    }
  ]
}

使用上面的控制器示例,我们可以捕获异常(如果需要)并执行附加逻辑

try {
    $actor = $this->Actors->newEmptyEntity();
    $actor = $this->Actors->patchEntity($actor, $this->request->getData());
} catch (\MixerApi\ExceptionRender\ValidationException $e) {
    // do something here
}

异常

对于基于验证之外的非验证异常,即使是你项目自己的自定义异常,输出也与CakePHP原生输出类似,增加了异常属性。例如,MethodNotAllowedException将导致

{
  "exception": "MethodNotAllowedException",
  "message": "Your exception message here",
  "url": "/actors",
  "code": 405
}

例如,如果您有一个抛出的自定义异常,例如InventoryExceededException,您将看到

{
  "exception": "InventoryExceededException",
  "message": "No inventory exists",
  "url": "/requested-url",
  "code": 500
}

提供异常名称,结合CakePHP已提供的状态代码,使API客户端能够调整其异常处理。

禁用ValidationExceptions

有时您可能不想让ValidationExceptions运行。您可以轻松禁用此事件

Configure::write('MixerApi.ExceptionRender.entity_validation', false);

另一个例子是,您可能只想为应用程序的非CLI部分运行此事件

Configure::write('MixerApi.ExceptionRender.entity_validation', PHP_SAPI !== 'cli');

更改错误消息

ExceptionRender触发一个MixerApi.ExceptionRender.beforeRender事件,您可以监听该事件来修改viewVarsserialize变量。这两个变量都可通过MixerApi\ExceptionRender\ErrorDecorator访问。

示例

<?php
declare(strict_types=1);

namespace App\Event;

use Cake\Event\EventListenerInterface;
use MixerApi\ExceptionRender\ErrorDecorator;
use MixerApi\ExceptionRender\MixerApiExceptionRenderer;

class ExceptionRender implements EventListenerInterface
{
    public function implementedEvents(): array
    {
        return [
            'MixerApi.ExceptionRender.beforeRender' => 'beforeRender'
        ];
    }

    /**
     * @param \Cake\Event\Event $event
     */
    public function beforeRender(\Cake\Event\Event $event)
    {
        $errorDecorator = $event->getSubject();
        $data = $event->getData();

        if (!$errorDecorator instanceof ErrorDecorator || !$data['exception'] instanceof MixerApiExceptionRenderer) {
            return;
        }

        if (!$data['exception']->getError() instanceof \Authentication\Authenticator\UnauthenticatedException) {
            return;
        }

        $viewVars = $errorDecorator->getViewVars();
        $viewVars['message'] = 'A custom unauthenticated message';
        $errorDecorator->setViewVars($viewVars);
    }
}

有关官方CakePHP文档中的事件的更多信息。