Description
Working on Reservation Validation we found out next:
I've added validation for ReservationBuilder but I think there is a general issue.
The __construct() signature of \Magento\Framework\Exception\AbstractAggregateException class and the one of its descendant \Magento\Framework\Validation\ValidationException are different.
This causes an issue in the addError() method when more than a validation error occurs because $this->originalPhrase is not properly initialized in ValidationException and we have render() called on a null object.
you are totally correct. The ValidationException
namespace Magento\Framework\Validation;
use Magento\Framework\Exception\AbstractAggregateException;
/**
* Add possibility to set several messages to exception
*
* @api
*/
class ValidationException extends AbstractAggregateException
{
/**
* @param ValidationResult $validationResult
* @param \Exception $cause
* @param int $code
*/
public function __construct(ValidationResult $validationResult, \Exception $cause = null, $code = 0)
{
foreach ($validationResult->getErrors() as $error) {
$this->addError($error);
}
parent::__construct($this->phrase, $cause, $code);
}
}
violates 4 main rules which should be followed by Magento constructors:
- It's forbidden to have business logic in the Magento Constructors, just assignments allowed
- As a consequence of 1. the signature of the child doesn't correspond to parent's signature (which is not recommended).
- As a consequence of 1. parent constructor not called as a first line in child constructor. (Following the rule of calling parent's constructor in the very beginning of child constructor is a save way to be sure that you have a correctly instantiated base implementation. For example, in Java super constructor MUST be called at the first line of the child).
- As a consequence of all of the above, call
$this->addError($error);
which uses parent's contract relies on$this->phrase
which is not initialized at this moment.
So, the problem appeared as an outcome of item 4.
But before that 3 items were violated, which made it possible to make a logical error in item 4,