How do you customize exception format with FOSRestBundle and Symfony 2?
Asked Answered
E

2

9

I'm using FOSRestBundle with Symfony 2 to implement a REST API in JSON format.

I want all API exceptions to be returned in a specific JSON format like this:

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

How do I do this?

I've tried to fiddle with ExceptionController, but it's logic seems too complicated to be easily overloaded.

Encephalon answered 11/6, 2015 at 11:55 Comment(1)
Did you solve this? I've got the same troubleTh
F
10

Note: This works only for FOSResBundle < 2.0. For FOSResBundle >= 2.0 please use Exception Normalizers, see examples.

You can write custom exception wrapper handler like in docs. In your case:

<?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;
    }
}

app/config/config.yml

fos_rest:
    routing_loader:
        default_format: json

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

    exception:
          enabled: true

Response example:

{"success":false,"exception":{"exceptionClass":"Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException","message":"Not Found"}}
Fontes answered 11/6, 2015 at 14:8 Comment(4)
I think this answer may no longer be valid. FOSRestBundle no longer includes an exception wrapper handler class or interface from what I can see.Polyunsaturated
This is deprecated since v2.0 of FOS Rest. Another idea?Th
Yes, it's deprecated because now it depends on your serializer. So you should find the way how to modify exception using your serializer. I would add example but I'm afraid answer will be too big. For example normalizer for JMSSerializerBundle github.com/FriendsOfSymfony/FOSRestBundle/blob/2.0/Serializer/…Fontes
As @ArtemZhuravlev said, there are default serializers: JMS ExceptionHandler and Symfony ExceptionNormalizer. You may extend it in services :)Tallboy
H
6

I've landed on this thread a number of times over the last few days. For anyone else in my situation where you are using V2 of the bundle, you may find the following resource on upgrading FOSRestBundle useful.

It covers the use of serializer in place of ExceptionWrapperHandlerInterface.

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

  • The exception_wrapper_handler config option was removed. Use normalizers instead.

Before:

config.yml

fos_rest:
   view:
       exception_wrapper_handler: AppBundle\ExceptionWrapperHandler

Handler

namespace AppBundle;

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

After (if you use the Symfony serializer):

services.yml

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

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;
   }
}
Horde answered 6/2, 2017 at 6:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.