ExceptionFactory¶
Published: 2019-06-14
Author: Nickolas Burr
Description¶
There are several benefits to using factories in Magento, namely flexible, stateless object creation. As such, factories have become widely adopted and utilized in Magento 2, and can be seen as one of the most significant architectural improvements over Magento 1. However, it’s noticeable that exception creation practices have yet to embrace factories.
In the example below, we introduce the ExceptionFactory
class, which can be used to create
Throwable
[1] exception types. The reasons for defining this class statically include:
Enforce
$type
argument to implementThrowable
interfaceAllow any
Throwable
exception type, instead of single exception type
Note
The ExceptionFactory
class will only create an exception type. It is the
responsibility of the invoking method to throw the created exception instance.
Usage¶
<?php
...
/** @var EntityInterface $entity */
$entity = $this->entityFactory->create();
$this->entityResource->load(
$entity,
$id
);
if (!$entity->getId()) {
/** @var NoSuchEntityException $exception */
$exception = $this->exceptionFactory->create(
NoSuchEntityException::class,
__('No such entity found.')
);
throw $exception;
}
...
Source¶
Below is an example ExceptionFactory
that can be used in modules:
<?php
/**
* ExceptionFactory.php
*
* Factory for generating various exception types.
* Requires ObjectManager for instance generation.
*
* @link https://devdocs.magento.com/guides/v2.3/extension-dev-guide/factories.html
*/
declare(strict_types=1);
namespace Vendor\Package\Exception;
use Exception;
use Magento\Framework\{
ObjectManagerInterface,
Phrase
};
use Throwable;
class ExceptionFactory
{
/** @constant string BASE_TYPE */
public const BASE_TYPE = Exception::class;
/** @constant string DEFAULT_ERROR */
public const DEFAULT_ERROR = 'An error was encountered.';
/** @property ObjectManagerInterface $objectManager */
protected $objectManager;
/**
* @param ObjectManagerInterface $objectManager
* @return void
*/
public function __construct(
ObjectManagerInterface $objectManager
) {
$this->objectManager = $objectManager;
}
/**
* @param string|null $type
* @param Phrase|null $message
* @return mixed
* @throws Exception
*/
public function create(
?string $type = self::BASE_TYPE,
?Phrase $message = null
) {
/** @var array $arguments */
$arguments = [];
/* If no message was given, set default message. */
$message = $message ?? __(self::ERROR_DEFAULT);
if (!is_subclass_of($type, Throwable::class)) {
throw new Exception(
__(
'Invalid exception type %1 was given.',
$type
)->__toString()
);
}
if ($type !== self::BASE_TYPE) {
$arguments['message'] = $message->__toString();
} else {
$arguments['phrase'] = $message;
}
return $this->objectManager->create($type, $arguments);
}
}