phpsymfonysymfony-validator

ConstraintViolationListInterface to Exception in Symfony


I need to convert an object of type ConstraintViolationListInterface to a single exception for further logging, where the message is a concatenation of the messages from each constraint violation on the list, when the validation fails.

Obviously I can't repeat a foreach loop in every bundle using validation to achieve this, therefore I was thinking about creating one more bundle providing a simple service accepting ConstraintViolationListInterface and returning a single exception. Is there a standard solution for this in Symfony? Seems weird that I need to write this service, the problem seems to be common to me.


Solution

  • I also was surprised that symfony has nothing helpful for this, that's why I've created my custom exception:

    class ValidationException extends \Exception
    {
        private $violations;
    
        public function __construct(array $violations)
        {
            $this->violations = $violations;
            parent::__construct('Validation failed.');
        }
    
        public function getMessages()
        {
            $messages = [];
            foreach ($this->violations as $paramName => $violationList) {
                foreach ($violationList as $violation) {
                    $messages[$paramName][] = $violation->getMessage();
                }
            }
            return $messages;
        }
    
        public function getJoinedMessages()
        {
            $messages = [];
            foreach ($this->violations as $paramName => $violationList) {
                foreach ($violationList as $violation) {
                    $messages[$paramName][] = $violation->getMessage();
                }
                $messages[$paramName] = implode(' ', $messages[$paramName]);
            }
            return $messages;
        }
    }
    

    All code available here.

    And I use this exception in a next way:

    try {
        $errors = $validator->validate(...);
        if (0 !== count($errors)) {
            throw new ValidationException($errors);
        }
    } catch (ValidationException $e) {
        // Here you can obtain your validation errors. 
        var_dump($e->getMessages());
    }