3
votes

Shortly: how can you set a specific http error code, instead of a generic 500, when a constraint fails on entity save?

Details

I'm using Symfony custom constraint @UniqueEntity (http://symfony.com/doc/current/reference/constraints/UniqueEntity.html) to assert that some data is not duplicated when saving an entity.

If this constraint check results in a violation, I get a 500 http code, while others may be more appropriate, e.g. 409 - Conflict (https://httpstatuses.com/409).

I can't seem to find any documentation on how to override the validation response.

Thank you in advance for any suggestion.

2
Did you manage to find a solution for the UniqueEntity constraint ?Pierrick Martellière
@PierrickMartellière no but you can use an actual constraint like this * @ORM\Table(name="company", uniqueConstraints={ * @ORM\UniqueConstraint(name="code_idx", columns={"code"}) * })Francesco Abeni
Isn't this similar to @UniqueEntity() ?Pierrick Martellière
@PierrickMartellière yes, but a correct exception is thrown. See my last comment in the accepted answer below.Francesco Abeni
Yes, I pointed you to that comment to explain the reason I had to use a different annotation. Hope this helps.Francesco Abeni

2 Answers

2
votes

Maybe you could create a Listener to the event : kernel.exception

And then you will have something like :

<?php

public function onKernelException(GetResponseForExceptionEvent $event)
{
      $e = $event->getException();

      if ($e instanceof NameOfTheException) {
            // logic here

            return (new Response())
                  ->setStatusCode(409)
            ;
      }
}
1
votes

Just catch exception in controller:

public function saveAction()
{
    try {
       $entity = new Entity('duplicate name');

       $this->entityManager->persist($entity);
       $this->entityManager->flush();

       return new Response();
    } catch(UniqueConstraintViolationException $e) {
       return new Response('Entity with same name already exists', Response::HTTP_CONFLICT);
    } catch (\Exception $e) {
       return new Response('Internal error', Response::HTTP_INTERNAL_SERVER_ERROR);
    }
}