Skip to content

Commit 92fd971

Browse files
committed
fix mapping exception classes to response status codes
1 parent 91fe647 commit 92fd971

File tree

12 files changed

+92
-8
lines changed

12 files changed

+92
-8
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
2.8.2
5+
-----
6+
7+
* fixed embedding status codes in the response body when a mapping of exception classes to status
8+
codes is configured
9+
410
2.8.1
511
-----
612

DependencyInjection/FOSRestExtension.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -420,13 +420,13 @@ private function loadException(array $config, XmlFileLoader $loader, ContainerBu
420420
->replaceArgument(0, $config['exception']['messages']);
421421

422422
$container->getDefinition('fos_rest.serializer.flatten_exception_handler')
423-
->replaceArgument(1, $config['exception']['debug']);
423+
->replaceArgument(2, $config['exception']['debug']);
424424
$container->getDefinition('fos_rest.serializer.flatten_exception_handler')
425-
->replaceArgument(2, 'rfc7807' === $config['exception']['flatten_exception_format']);
425+
->replaceArgument(3, 'rfc7807' === $config['exception']['flatten_exception_format']);
426426
$container->getDefinition('fos_rest.serializer.flatten_exception_normalizer')
427-
->replaceArgument(1, $config['exception']['debug']);
427+
->replaceArgument(2, $config['exception']['debug']);
428428
$container->getDefinition('fos_rest.serializer.flatten_exception_normalizer')
429-
->replaceArgument(2, 'rfc7807' === $config['exception']['flatten_exception_format']);
429+
->replaceArgument(3, 'rfc7807' === $config['exception']['flatten_exception_format']);
430430

431431
if ($config['exception']['serialize_exceptions']) {
432432
$container->getDefinition('fos_rest.serializer.exception_normalizer.jms')

Resources/config/exception.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,15 @@
4747
</service>
4848

4949
<service id="fos_rest.serializer.flatten_exception_handler" class="FOS\RestBundle\Serializer\Normalizer\FlattenExceptionHandler" public="false">
50+
<argument type="service" id="fos_rest.exception.codes_map" /> <!-- exception messages -->
5051
<argument type="service" id="fos_rest.exception.messages_map" /> <!-- exception messages -->
5152
<argument /><!-- show exception message -->
5253
<argument /><!-- render according to RFC 7807 -->
5354
<tag name="jms_serializer.subscribing_handler" />
5455
</service>
5556

5657
<service id="fos_rest.serializer.flatten_exception_normalizer" class="FOS\RestBundle\Serializer\Normalizer\FlattenExceptionNormalizer" public="false">
58+
<argument type="service" id="fos_rest.exception.codes_map" /> <!-- exception messages -->
5759
<argument type="service" id="fos_rest.exception.messages_map" /> <!-- exception messages -->
5860
<argument /><!-- show exception message -->
5961
<argument /><!-- render according to RFC 7807 -->

Serializer/Normalizer/FlattenExceptionHandler.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
*/
1919
class FlattenExceptionHandler implements SubscribingHandlerInterface
2020
{
21+
private $statusCodeMap;
2122
private $messagesMap;
2223
private $debug;
2324
private $rfc7807;
2425

25-
public function __construct(ExceptionValueMap $messagesMap, bool $debug, bool $rfc7807)
26+
public function __construct(ExceptionValueMap $statusCodeMap, ExceptionValueMap $messagesMap, bool $debug, bool $rfc7807)
2627
{
28+
$this->statusCodeMap = $statusCodeMap;
2729
$this->messagesMap = $messagesMap;
2830
$this->debug = $debug;
2931
$this->rfc7807 = $rfc7807;
@@ -94,7 +96,7 @@ private function convertToArray(FlattenException $exception, Context $context):
9496
{
9597
if ($context->hasAttribute('status_code')) {
9698
$statusCode = $context->getAttribute('status_code');
97-
} else {
99+
} elseif (false === $statusCode = $this->statusCodeMap->resolveFromClassName($exception->getClass())) {
98100
$statusCode = $exception->getStatusCode();
99101
}
100102

Serializer/Normalizer/FlattenExceptionNormalizer.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@
2323
*/
2424
final class FlattenExceptionNormalizer implements NormalizerInterface
2525
{
26+
private $statusCodeMap;
2627
private $messagesMap;
2728
private $debug;
2829
private $rfc7807;
2930

30-
public function __construct(ExceptionValueMap $messagesMap, bool $debug, bool $rfc7807)
31+
public function __construct(ExceptionValueMap $statusCodeMap, ExceptionValueMap $messagesMap, bool $debug, bool $rfc7807)
3132
{
33+
$this->statusCodeMap = $statusCodeMap;
3234
$this->messagesMap = $messagesMap;
3335
$this->debug = $debug;
3436
$this->rfc7807 = $rfc7807;
@@ -38,7 +40,7 @@ public function normalize($exception, $format = null, array $context = [])
3840
{
3941
if (isset($context['status_code'])) {
4042
$statusCode = $context['status_code'];
41-
} else {
43+
} elseif (false === $statusCode = $this->statusCodeMap->resolveFromClassName($exception->getClass())) {
4244
$statusCode = $exception->getStatusCode();
4345
}
4446

Tests/Functional/Bundle/TestBundle/Controller/SerializerErrorController.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ public function unknownExceptionAction()
3333
throw new \OutOfBoundsException('Unknown exception message.');
3434
}
3535

36+
public function invalidArgumentExceptionAction()
37+
{
38+
throw new \InvalidArgumentException('Invalid argument given.');
39+
}
40+
3641
/**
3742
* @View
3843
*/

Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ test_serializer_unknown_exception:
1010
path: /serializer-error/unknown_exception.{_format}
1111
defaults: { _controller: FOS\RestBundle\Tests\Functional\Bundle\TestBundle\Controller\SerializerErrorController::unknownExceptionAction }
1212

13+
test_serializer_invalid_argument_exception:
14+
path: /serializer-error/invalid-argument-exception.{_format}
15+
defaults: { _controller: FOS\RestBundle\Tests\Functional\Bundle\TestBundle\Controller\SerializerErrorController::invalidArgumentExceptionAction }
16+
1317
test_serializer_error_invalid_form:
1418
path: /serializer-error/invalid-form.{_format}
1519
defaults: { _controller: FOS\RestBundle\Tests\Functional\Bundle\TestBundle\Controller\SerializerErrorController::invalidFormAction }

Tests/Functional/SerializerErrorTest.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,61 @@ public function testSerializeUnknownExceptionJsonWithoutDebugUsingErrorRenderer(
155155
$this->assertEquals('{"code":500,"message":"Internal Server Error"}', $client->getResponse()->getContent());
156156
}
157157

158+
/**
159+
* @dataProvider serializeExceptionCodeMappedToResponseStatusCodeJsonProvider
160+
*/
161+
public function testSerializeExceptionCodeMappedToResponseStatusCodeJsonUsingErrorRenderer(string $testCase, array $expectedJson)
162+
{
163+
if (!class_exists(SerializerErrorRenderer::class)) {
164+
$this->markTestSkipped();
165+
}
166+
167+
$this->iniSet('error_log', file_exists('/dev/null') ? '/dev/null' : 'nul');
168+
169+
$client = $this->createClient(array('test_case' => $testCase, 'debug' => false));
170+
$client->request('GET', '/serializer-error/invalid-argument-exception.json');
171+
172+
$this->assertEquals(json_encode($expectedJson), $client->getResponse()->getContent());
173+
}
174+
175+
public function serializeExceptionCodeMappedToResponseStatusCodeJsonProvider(): array
176+
{
177+
return [
178+
[
179+
'FlattenExceptionHandlerLegacyFormat',
180+
[
181+
'code' => 400,
182+
'message' => 'Invalid argument given.',
183+
],
184+
],
185+
[
186+
'FlattenExceptionHandlerRfc7807Format',
187+
[
188+
'type' => 'https://tools.ietf.org/html/rfc2616#section-10',
189+
'title' => 'An error occurred',
190+
'status' => 400,
191+
'detail' => 'Invalid argument given.',
192+
],
193+
],
194+
[
195+
'FlattenExceptionNormalizerLegacyFormat',
196+
[
197+
'code' => 400,
198+
'message' => 'Invalid argument given.',
199+
],
200+
],
201+
[
202+
'FlattenExceptionNormalizerRfc7807Format',
203+
[
204+
'type' => 'https://tools.ietf.org/html/rfc2616#section-10',
205+
'title' => 'An error occurred',
206+
'status' => 400,
207+
'detail' => 'Invalid argument given.',
208+
],
209+
],
210+
];
211+
}
212+
158213
/**
159214
* @group legacy
160215
*

Tests/Functional/app/FlattenExceptionHandlerLegacyFormat/config.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ imports:
44

55
fos_rest:
66
exception:
7+
codes:
8+
'InvalidArgumentException': 400
79
exception_listener: false
810
serialize_exceptions: false
911
flatten_exception_format: 'legacy'

Tests/Functional/app/FlattenExceptionHandlerRfc7807Format/config.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ imports:
44

55
fos_rest:
66
exception:
7+
codes:
8+
'InvalidArgumentException': 400
79
exception_listener: false
810
serialize_exceptions: false
911
flatten_exception_format: 'rfc7807'

0 commit comments

Comments
 (0)