如何使用FOSRestBundle和Symfony 2自定义异常格式?

Sla*_* II 9 rest json exception symfony fosrestbundle

我正在使用FOSRestBundle和Symfony 2来实现JSON格式的REST API.

我希望以特定的JSON格式返回所有API异常,如下所示:

{
    "success": false,
    "exception": {
        "exceptionClass": "SomeNastyException",
        "message": "A nasty exception occurred"
    }
}
Run Code Online (Sandbox Code Playgroud)

我该怎么做呢?

我试图摆弄ExceptionController,但它的逻辑看起来太复杂了,不容易重载.

Art*_*lev 10

注意:这仅适用于FOSResBundle <2.0.对于FOSResBundle> = 2.0,请使用Exception Normalizers,请参阅示例.

您可以像在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;
    }
}
Run Code Online (Sandbox Code Playgroud)

应用程序/配置/ config.yml

fos_rest:
    routing_loader:
        default_format: json

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

    exception:
          enabled: true
Run Code Online (Sandbox Code Playgroud)

响应示例:

{"success":false,"exception":{"exceptionClass":"Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException","message":"Not Found"}}
Run Code Online (Sandbox Code Playgroud)


小智 5

在过去的几天里,我已多次登陆这个帖子.对于我使用捆绑软件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
Run Code Online (Sandbox Code Playgroud)

处理器

namespace AppBundle;

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

之后(如果您使用Symfony序列化程序):

services.yml

services:
   app_bundle.exception_normalizer:
       class: AppBundle\Normalizer\ExceptionNormalizer
       tags:
           - { name: serializer.normalizer }
Run Code Online (Sandbox Code Playgroud)

正规化

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;
   }
}
Run Code Online (Sandbox Code Playgroud)