diff --git a/src/ExceptionBasedCondition.php b/src/ExceptionBasedCondition.php index 51e1da5..237302c 100644 --- a/src/ExceptionBasedCondition.php +++ b/src/ExceptionBasedCondition.php @@ -20,7 +20,9 @@ namespace CrowdStar\Backoff; +use Exception as BaseException; use ReflectionClass; +use Throwable; /** * Class ExceptionBasedCondition @@ -71,17 +73,26 @@ public function getException(): string */ public function setException(string $exception): self { - if (!class_exists($exception)) { - throw new Exception("Exception class {$exception} not exists"); - } + if (class_exists($exception)) { + $class = new ReflectionClass($exception); + if ((BaseException::class != $class->getName()) && !$class->isSubclassOf(BaseException::class)) { + throw new Exception("{$exception} objects are not instances of class \Exception"); + } - $class = new ReflectionClass($exception); - if ((\Exception::class != $class->getName()) && !$class->isSubclassOf(\Exception::class)) { - throw new Exception("{$exception} objects are not instance of class \Exception"); - } + $this->exception = $exception; + + return $this; + } elseif (interface_exists($exception)) { + $class = new ReflectionClass($exception); + if ((Throwable::class != $class->getName()) && !$class->implementsInterface(Throwable::class)) { + throw new Exception("{$exception} objects are not instances of interface \Throwable"); + } - $this->exception = $exception; + $this->exception = $exception; + + return $this; + } - return $this; + throw new Exception("Class/interface \"{$exception}\" does not exist"); } } diff --git a/tests/unit/ExceptionBasedConditionTest.php b/tests/unit/ExceptionBasedConditionTest.php index b343afd..c2fa939 100644 --- a/tests/unit/ExceptionBasedConditionTest.php +++ b/tests/unit/ExceptionBasedConditionTest.php @@ -20,6 +20,7 @@ namespace CrowdStar\Tests\Backoff; +use ArrayAccess; use BadFunctionCallException; use BadMethodCallException; use CrowdStar\Backoff\ExceptionBasedCondition; @@ -29,6 +30,7 @@ use LogicException; use PHPUnit\Framework\ExpectationFailedException; use PHPUnit\Framework\TestCase; +use Throwable; use TypeError; /** @@ -43,6 +45,11 @@ public function dataSuccessfulRetries(): array // @see http://php.net/manual/en/spl.exceptions.php SPL exceptions // Exception > LogicException > BadFunctionCallException > BadMethodCallException return [ + [ + Throwable::class, + Exception::class, + 'try to catch a throwable object that implements interface \throwable.', + ], [ Exception::class, Exception::class, @@ -179,6 +186,9 @@ function () use ($helper) { public function dataSetException(): array { return [ + [ + Throwable::class, + ], [ Exception::class, ], @@ -213,15 +223,19 @@ public function dataSetExceptionWithExceptions(): array { return [ [ - 'Exception class \CrowdStar\Backoff\a_non_existing_class_name not exists', + 'ArrayAccess objects are not instances of interface \Throwable', + ArrayAccess::class, + ], + [ + 'Class/interface "\CrowdStar\Backoff\a_non_existing_class_name" does not exist', '\CrowdStar\Backoff\a_non_existing_class_name', ], [ - 'Error objects are not instance of class \Exception', + 'Error objects are not instances of class \Exception', Error::class, ], [ - 'TypeError objects are not instance of class \Exception', + 'TypeError objects are not instances of class \Exception', TypeError::class, ], ];