Skip to content

Commit 5bbf8f5

Browse files
committed
Added ExceptionWrapperSerializeHandler so ExceptionWrapper could be serialized properly
1 parent d37f441 commit 5bbf8f5

File tree

4 files changed

+178
-0
lines changed

4 files changed

+178
-0
lines changed

Resources/config/view.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<parameter key="fos_rest.view.exception_wrapper_handler" />
1212
<parameter key="fos_rest.view_handler.default.class">FOS\RestBundle\View\ViewHandler</parameter>
1313
<parameter key="fos_rest.view_handler.jsonp.class">FOS\RestBundle\View\JsonpHandler</parameter>
14+
<parameter key="fos_rest.serializer.exception_wrapper_serialize_handler.class">FOS\RestBundle\Serializer\ExceptionWrapperSerializeHandler</parameter>
1415
</parameters>
1516

1617
<services>
@@ -42,5 +43,9 @@
4243

4344
<service id="fos_rest.view.exception_wrapper_handler" class="%fos_rest.view.exception_wrapper_handler%" />
4445

46+
<service id="fos_rest.serializer.exception_wrapper_serialize_handler" class="%fos_rest.serializer.exception_wrapper_serialize_handler.class%">
47+
<tag name="jms_serializer.subscribing_handler" />
48+
</service>
49+
4550
</services>
4651
</container>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
namespace FOS\RestBundle\Serializer;
4+
5+
use FOS\RestBundle\Util\ExceptionWrapper;
6+
use JMS\Serializer\Context;
7+
use JMS\Serializer\GraphNavigator;
8+
use JMS\Serializer\Handler\SubscribingHandlerInterface;
9+
use JMS\Serializer\VisitorInterface;
10+
11+
class ExceptionWrapperSerializeHandler implements SubscribingHandlerInterface
12+
{
13+
/**
14+
* @return array
15+
*/
16+
public static function getSubscribingMethods()
17+
{
18+
return array(
19+
array(
20+
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
21+
'format' => 'json',
22+
'type' => 'FOS\\RestBundle\\Util\\ExceptionWrapper',
23+
'method' => 'serializeToJson'
24+
)
25+
);
26+
}
27+
28+
/**
29+
* @param VisitorInterface $visitor
30+
* @param ExceptionWrapper $value
31+
* @param array $type
32+
* @param Context $context
33+
* @return string
34+
*/
35+
public function serializeToJson(
36+
VisitorInterface $visitor,
37+
ExceptionWrapper $value,
38+
array $type,
39+
Context $context
40+
) {
41+
$type['name'] = 'array';
42+
$data = array(
43+
'code' => $value->getCode(),
44+
'message' => $value->getMessage(),
45+
'errors' => $value->getErrors(),
46+
);
47+
return $visitor->visitArray($data, $type, $context);
48+
}
49+
}

Tests/View/ViewHandlerTest.php

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,22 @@
1111

1212
namespace FOS\RestBundle\Tests\View;
1313

14+
use FOS\RestBundle\Serializer\ExceptionWrapperSerializeHandler;
15+
use FOS\RestBundle\Util\ExceptionWrapper;
1416
use FOS\RestBundle\View\ExceptionWrapperHandler;
1517
use FOS\RestBundle\View\View;
1618
use FOS\RestBundle\View\ViewHandler;
19+
use JMS\Serializer\EventDispatcher\EventDispatcher;
20+
use JMS\Serializer\Handler\FormErrorHandler;
21+
use JMS\Serializer\Handler\HandlerRegistry;
22+
use JMS\Serializer\SerializerBuilder;
1723
use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference;
1824
use FOS\RestBundle\Util\Codes;
1925
use Symfony\Component\DependencyInjection\Container;
26+
use Symfony\Component\Form\Form;
27+
use Symfony\Component\Form\FormBuilder;
28+
use Symfony\Component\Form\FormError;
29+
use Symfony\Component\Form\Forms;
2030
use Symfony\Component\HttpFoundation\Request;
2131
use Symfony\Component\HttpFoundation\Response;
2232
use Symfony\Component\Form\FormView;
@@ -546,4 +556,92 @@ public function testConfigurableViewHandlerInterface()
546556
$this->assertEquals('1.1', $context->attributes->get('version')->getOrThrow(new \Exception('Serialization version not set as expected')));
547557
$this->assertTrue($context->shouldSerializeNull());
548558
}
559+
560+
public function testCreateResponseWithFormErrorsAndSerializationGroups()
561+
{
562+
$builder = Forms::createFormFactory()->createBuilder();
563+
$form = $builder
564+
->add('name', 'text')
565+
->add('description', 'text')
566+
->getForm();
567+
568+
$exceptionWrapper = new ExceptionWrapper(
569+
array(
570+
'status_code' => 400,
571+
'message' => 'Validation Failed',
572+
'errors' => $form
573+
)
574+
);
575+
576+
$view = new View($exceptionWrapper);
577+
$view->getSerializationContext()->setGroups(array('Custom'));
578+
579+
$handler = new ExceptionWrapperSerializeHandler();
580+
$formErrorHandlerMock = $this->getMock(
581+
'JMS\Serializer\Handler\FormErrorHandler',
582+
array('serializeFormToJson'),
583+
array(),
584+
'',
585+
false
586+
);
587+
$formErrorHandlerMock
588+
->expects($this->once())
589+
->method('serializeFormToJson')
590+
->with(
591+
$this->isInstanceOf('JMS\\Serializer\\JsonSerializationVisitor'),
592+
$form,
593+
array(
594+
'name' => 'Symfony\Component\Form\Form',
595+
'params' => array()
596+
)
597+
)
598+
->will(
599+
$this->returnValue(
600+
array(
601+
'children' => array(
602+
'name' => array(
603+
'errors' => array(
604+
'Invalid name'
605+
)
606+
),
607+
)
608+
)
609+
)
610+
);
611+
612+
$serializer = SerializerBuilder::create()
613+
->configureHandlers(function (HandlerRegistry $handlerRegistry) use ($handler, $formErrorHandlerMock) {
614+
$handlerRegistry->registerSubscribingHandler($handler);
615+
$handlerRegistry->registerSubscribingHandler($formErrorHandlerMock);
616+
})
617+
->build();
618+
619+
$container = $this->getMock('Symfony\Component\DependencyInjection\Container', array('get'));
620+
$container
621+
->expects($this->once())
622+
->method('get')
623+
->with('fos_rest.serializer')
624+
->will($this->returnValue($serializer));
625+
626+
$viewHandler = new ViewHandler(array());
627+
$viewHandler->setContainer($container);
628+
629+
$response = $viewHandler->createResponse($view, new Request(), 'json');
630+
631+
$expected = array(
632+
'code' => 400,
633+
'message' => 'Validation Failed',
634+
'errors' => array(
635+
'children' => array(
636+
'name' => array(
637+
'errors' => array(
638+
'Invalid name'
639+
)
640+
)
641+
)
642+
)
643+
);
644+
645+
$this->assertEquals($expected, json_decode($response->getContent(), true));
646+
}
549647
}

Util/ExceptionWrapper.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace FOS\RestBundle\Util;
1313

14+
use Symfony\Component\Form\FormInterface;
15+
1416
/**
1517
* Wraps an exception into the FOSRest exception format.
1618
*/
@@ -32,4 +34,28 @@ public function __construct($data)
3234
$this->errors = $data['errors'];
3335
}
3436
}
37+
38+
/**
39+
* @return int
40+
*/
41+
public function getCode()
42+
{
43+
return $this->code;
44+
}
45+
46+
/**
47+
* @return FormInterface
48+
*/
49+
public function getErrors()
50+
{
51+
return $this->errors;
52+
}
53+
54+
/**
55+
* @return string
56+
*/
57+
public function getMessage()
58+
{
59+
return $this->message;
60+
}
3561
}

0 commit comments

Comments
 (0)