问题描述
在将它们显示为JSON之后,我想拦截Symfony的所有错误。 在friendsofsymfony / rest-bundle v2中,我可以设置参数
fos_rest:
exception:
enabled: true
exception_controller: 'App\Controller\ExceptionController::showAction'
...
但是在V3中,参数exception_controller被删除了。
我当前的FOS REST配置:
fos_rest:
view:
formats:
xml: false
json: true
view_response_listener: force
serializer:
groups: ['Default']
serialize_null: true
format_listener:
rules:
- { path: ^/api/v1,priorities: [ json ],fallback_format: json,prefer_extension: true }
exception:
enabled: true
官方手册说应该在JMS中使用处理程序。 https://symfony.com/doc/current/bundles/FOSRestBundle/4-exception-controller-support.html 但这并没有说明如何在yaml中设置配置。
解决方法
您可以拦截symfony订阅者的所有错误
<?php
declare(strict_types=1);
namespace App\Util\Serializer\Normalizer;
use JMS\Serializer\Context;
use JMS\Serializer\GraphNavigatorInterface;
use JMS\Serializer\Handler\SubscribingHandlerInterface;
use JMS\Serializer\JsonSerializationVisitor;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
class CustomExceptionHandler implements SubscribingHandlerInterface
{
private bool $debug;
public function __construct(bool $kernelDebug)
{
$this->debug = $kernelDebug;
}
public static function getSubscribingMethods(): array
{
return [
[
'direction' => GraphNavigatorInterface::DIRECTION_SERIALIZATION,'format' => JsonEncoder::FORMAT,'type' => \Exception::class,'method' => 'serializeToJson','priority' => -1,],];
}
public function serializeToJson(
JsonSerializationVisitor $visitor,\Exception $exception,array $type,Context $context
) {
$data = $this->convertToArray($exception,$context);
return $visitor->visitArray($data,$type);
}
/**
* @return array<string,mixed>
*/
protected function convertToArray(\Exception $exception,Context $context): array
{
$statusCode = null;
if ($context->hasAttribute('template_data')) {
$templateData = $context->getAttribute('template_data');
if (array_key_exists('status_code',$templateData)) {
$statusCode = $templateData['status_code'];
}
}
$data['error'] = $this->getMessageFromThrowable($exception,$statusCode);
return $data;
}
protected function getMessageFromThrowable(\Throwable $throwable,?int $statusCode): string
{
if ($this->debug) {
return $throwable->getMessage();
}
return array_key_exists($statusCode,Response::$statusTexts) ? Response::$statusTexts[$statusCode] : 'error';
}
}
services.yaml
App\Utils\Serializer\Normalizer\CustomExceptionHandler:
$kernelDebug: '%kernel.debug%'