Description
Symfony version(s) affected
6.3.8
Description
The #[MapRequestPayload]
attribute handles invalid input (wrong type, missing fields) by returning a 422 Response and a message hinting at the problem(s). However when sending an invalid enum value, the result is a 500 Response.
How to reproduce
Given the following setup
enum Foo: string
{
case BAR = 'bar';
}
class Input
{
public function __construct(public readonly Foo $foo) {}
}
class TestController
{
#[Route(...)]
public function test(#[MapRequestPayload] Input $input)
{
// ...
}
}
If you send a request containing the following Json
{
"foo": "baz"
}
You get a 500 Response, even though a 422 would have been more sensible. The exception message is
[critical] Uncaught PHP Exception Symfony\Component\Serializer\Exception\InvalidArgumentException: "The data must belong to a backed enumeration of type Foo" at vendor/symfony/serializer/Normalizer/BackedEnumNormalizer.php line 80
Possible Solution
No response
Additional Context
The BackedEnumNormalizer
handles failure differently depending on whether the has_constructor
flag in the $context
is set:
try {
return $type::from($data);
} catch (\ValueError $e) {
if (isset($context['has_constructor'])) {
throw new InvalidArgumentException('The data must belong to a backed enumeration of type '.$type);
}
throw NotNormalizableValueException::createForUnexpectedDataType('The data must belong to a backed enumeration of type '.$type, $data, [$type], $context['deserialization_path'] ?? null, true, 0, $e);
}
The NotNormalizableValueException
case is handled in the RequestPayloadValueResolver
, the InvalidArgumentException
case is not.