Bug: the \Magento\Sales\Model\Order\CreditmemoRepository::save() method misses (does not log and does not show) the actual exception message on a credit memo saving falure

\Magento\Sales\Model\Order\CreditmemoRepository::save()




The next handling (of the CouldNotSaveException)

So, the innternal exception with the real error message is missed.

A right behaviour could be like for a payment authorization voiding:

See also:

How to fix

<?xml version='1.0'?>
<config
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"
>
	<!--
		2016-03-18
		«Bug: the @see \Magento\Sales\Model\Order\CreditmemoRepository::save() method
		misses (does not log and does not show) the actual exception message
		on a credit memo saving falure».
		https://mage2.pro/t/973
	-->
	<type name='Magento\Sales\Model\Order\CreditmemoRepository'>
		<plugin
			name='Df\Sales\Plugin\Model\Order\CreditmemoRepository'
			type='Df\Sales\Plugin\Model\Order\CreditmemoRepository'
		/>
	</type>
</config>
<?php
namespace Df\Sales\Plugin\Model\Order;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\Framework\Exception\LocalizedException as LE;
use Magento\Sales\Model\Order\CreditmemoRepository as Sb;
use Magento\Sales\Api\Data\CreditmemoInterface as CM;
class CreditmemoRepository {
	/**
	 * 2016-03-18
	 * «Bug: the @see \Magento\Sales\Model\Order\CreditmemoRepository::save() method
	 * misses (does not log and does not show) the actual exception message
	 * on a credit memo saving falure».
	 * https://mage2.pro/t/973
	 *
	 * @see \Magento\Sales\Model\Order\CreditmemoRepository::save()
	 * @param Sb $sb
	 * @param \Closure $proceed
	 * @param CM $element
	 * @return CM
	 * @throws CouldNotSaveException|LE;
	 */
	public function aroundSave(Sb $sb, \Closure $proceed, CM $element) {
		/** @var CM $result */
		try {
			$result = $proceed($element);
		}
		catch(CouldNotSaveException $e) {
			/** @var \Exception|null $previous */
			$previous = $e->getPrevious();
			throw $previous instanceof LE ? $previous : $e;
		}
		return $result;
	}
}