Как настроить формат исключения с помощью FOSRestBundle и Symfony 2?

Я использую FOSRestBundle с Symfony 2 для реализации REST API в формате JSON.

Я хочу, чтобы все исключения API возвращались в определенном формате JSON, например:

{
    "success": false,
    "exception": {
        "exceptionClass": "SomeNastyException",
        "message": "A nasty exception occurred"
    }
}

Как мне это сделать?

Я пытался возиться с ExceptionController, но его логика кажется слишком сложно легко перегрузить.


person Slava Fomin II    schedule 11.06.2015    source источник
comment
Вы решили это? у меня такая же беда   -  person Dani Tome    schedule 12.12.2016


Ответы (2)


Примечание. Это работает только для FOSResBundle ‹ 2.0. Для FOSResBundle ›= 2.0 используйте нормализаторы исключений, см. примеры.

Вы можете написать собственный обработчик исключения, как в docs. В твоем случае:

<?php
//AppBundle\Handler\MyExceptionWrapperHandler.php
namespace AppBundle\Handler;

use FOS\RestBundle\Util\ExceptionWrapper;
use FOS\RestBundle\View\ExceptionWrapperHandlerInterface;

class MyExceptionWrapperHandler implements ExceptionWrapperHandlerInterface {

    public function wrap($data)
    {
        /** @var \Symfony\Component\Debug\Exception\FlattenException $exception */
        $exception = $data['exception'];

        $newException = array(
            'success' => false,
            'exception' => array(
                'exceptionClass' => $exception->getClass(),
                'message' => $data['status_text']
            )
        );

        return $newException;
    }
}

приложение/config/config.yml

fos_rest:
    routing_loader:
        default_format: json

    view:
        view_response_listener: force
        exception_wrapper_handler: AppBundle\Handler\MyExceptionWrapperHandler

    exception:
          enabled: true

Пример ответа:

{"success":false,"exception":{"exceptionClass":"Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException","message":"Not Found"}}
person Artem Zhuravlev    schedule 11.06.2015
comment
Я думаю, что этот ответ может быть недействительным. Насколько я вижу, FOSRestBundle больше не включает в себя класс обработчика исключений или интерфейс. - person RonnyKnoxville; 09.12.2016
comment
Это устарело, начиная с версии 2.0 FOS Rest. Еще одна идея? - person Dani Tome; 12.12.2016
comment
Да, это устарело, потому что теперь это зависит от вашего сериализатора. Поэтому вы должны найти способ изменить исключение с помощью вашего сериализатора. Я бы добавил пример, но боюсь, что ответ будет слишком большим. Например, нормализатор для JMSSerializerBundle github.com/FriendsOfSymfony/FOSRestBundle/blob /2.0/Сериализатор/ - person Artem Zhuravlev; 12.12.2016
comment
Как сказал @ArtemZhuravlev, есть сериализаторы по умолчанию: JMS ExceptionHandler и Symfony ExceptionNormalizer. Вы можете расширить его в сервисах :) - person zored; 26.02.2019

Я приземлялся на эту тему несколько раз за последние несколько дней. Для любого другого в моей ситуации, когда вы используете V2 пакета, вы можете найти следующий ресурс по обновлению FOSRestBundle полезным.

Он охватывает использование сериализатора вместо ExceptionWrapperHandlerInterface.

https://github.com/FriendsOfSymfony/FOSRestBundle/blob/master/UPGRADING-2.0.md

  • Опция конфигурации exception_wrapper_handler была удалена. Вместо этого используйте нормализаторы.

До:

config.yml

fos_rest:
   view:
       exception_wrapper_handler: AppBundle\ExceptionWrapperHandler

Обработчик

namespace AppBundle;

class ExceptionWrapperHandler implements ExceptionWrapperHandlerInterface
{
   public function wrap($data)
   {
       return new ExceptionWrapper(array('status_code' => 'foo'));
   }
}

После (если вы используете сериализатор Symfony):

services.yml

services:
   app_bundle.exception_normalizer:
       class: AppBundle\Normalizer\ExceptionNormalizer
       tags:
           - { name: serializer.normalizer }

нормализатор

namespace AppBundle\Normalizer;

use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

class ExceptionNormalizer implements NormalizerInterface
{
   public function normalize($object, $format = null, array $context = array())
   {
       return array('status_code' => 'foo');
   }

   public function supportsNormalization($data, $format = null)
   {
       return $data instanceof \My\Exception;
   }
}
person falconsmilie    schedule 06.02.2017