Skip to content

#[MapRequestPayload] does not handle invalid enums gracefully #52705

Open
@cgrabenstein

Description

@cgrabenstein

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions