#symfony #fosrestbundle #jmsserializerbundle #jms-serializer
#symfony #fosrestbundle #jmsserializerbundle #jms-сериализатор
Вопрос:
Я хочу перехватить все ошибки Symfony, после чего отобразить их в JSON. В friendsofsymfony / rest-bundle v2 я могу установить параметры
fos_rest:
exception:
enabled: true
exception_controller: 'AppControllerExceptionController::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.
Ответ №1:
Вы можете перехватывать все ошибки подписчика symfony
<?php
declare(strict_types=1);
namespace AppUtilSerializerNormalizer;
use JMSSerializerContext;
use JMSSerializerGraphNavigatorInterface;
use JMSSerializerHandlerSubscribingHandlerInterface;
use JMSSerializerJsonSerializationVisitor;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentSerializerEncoderJsonEncoder;
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
AppUtilsSerializerNormalizerCustomExceptionHandler:
$kernelDebug: '%kernel.debug%'