Magento 2 – Catch Errors from Validation When Saving Product or Category

magento2programmaticallyvalidation

I would like to validate the data before saving a product programatically because ->save() saves a product even if it doesn't have an sku.

If I do ->validate() I get the expected error:

[Magento\Eav\Model\Entity\Attribute\Exception]  
  The value of attribute "sku" must be set  

But I would like to catch that error and log it somewhere and let the script continue on another product.

This doesn't work:

try{
    $product->validate();
} catch(Exception $e){
}

If I look at the validate method it doesn't supply much info about where can I catch the error (except for that @todo):

\module-catalog\model\Product.php
    /**
         * Validate Product Data
         *
         * @todo implement full validation process with errors returning which are ignoring now
         *
         * @return array
         */
        public function validate()
        {
            $this->_eventManager->dispatch($this->_eventPrefix . '_validate_before', $this->_getEventData());
            $result = $this->_getResource()->validate($this);
            $this->_eventManager->dispatch($this->_eventPrefix . '_validate_after', $this->_getEventData());
            return $result;
        }

I imagine it is quite a common task. Does anyone have any solutions?

Best Answer

You can check like this:

$errors = $product->validate();
//validate returns true if everything is ok and an array with the errors otherwise
if (is_array($errors)) { 
    //log your errors
} else {
    //proceed to save
}

The errors array should look like this:

array(
     'attribute_code1_here' => 'Error message 1 here',
     'attribute_code2_here' => 'Error message 2 here',
     ....
)

There is a catch also.
If the product is not assigned to an attribute set, you will get only this error

array('attribute_set' => 'Invalid attribute set entity type');  

all the other errors will not be shown for that product.

For the categories it works the same without the restriction on the attribute set because there is only one attribute set for the categories.

[EDIT]
before calling $product->validate() call this:

$product->setCollectExceptionMessages(true); 

This will collect all the validation error messages inside an array and it will not throw an exception.

Related Topic