From aa66ef559eae03ea417eb875a3771e7336366499 Mon Sep 17 00:00:00 2001 From: Demin Yin Date: Wed, 8 Dec 2021 12:39:53 -0800 Subject: [PATCH] doing exponential backoff when throwable objects are thrown out --- src/ExceptionBasedCondition.php | 29 +++++++++++++++------- tests/unit/ExceptionBasedConditionTest.php | 20 ++++++++++++--- 2 files changed, 37 insertions(+), 12 deletions(-) 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, ], ];