diff --git a/src/ArraySerializerTrait.php b/src/ArraySerializerTrait.php deleted file mode 100644 index 9a32182..0000000 --- a/src/ArraySerializerTrait.php +++ /dev/null @@ -1,74 +0,0 @@ -|string - */ - abstract protected function getSourceFor(\Throwable $e, bool $isString = false): array|string; - - /** - * The method serialized errors BaseExceptionI to an array. - * - * @param BaseExceptionInterface[]|\Throwable[]|BaseExceptionInterface $errors array of errors - * @return array - */ - protected function errorsToArray(mixed $errors): array - { - if ($errors instanceof BaseExceptionInterface) { - $errors = [$errors]; - } - - $results = []; - - foreach ($errors as $error) { - if ($error instanceof BaseExceptionInterface) { - /* @var BaseExceptionInterface $error */ - $results[] = $error->toArray(); - } elseif ($error instanceof \Throwable) { - /* @var \Exception $error */ - $results[] = - [ - 'type' => $error::class, - 'source' => $this->getSourceFor($error), - 'message' => $error->getMessage(), - 'code' => $error->getCode(), - ]; - } - } - - return $results; - } - - /** - * The method deserialized array of array to array of errors. - * - * @param array> $array array of array - * @param string $class class for exception - * - * @return BaseException[] - * - * @throws \UnexpectedValueException - */ - protected function arrayToErrors(array $array, string $class = BaseException::class): array - { - $results = []; - - foreach ($array as $error) { - if (!\is_array($error)) { - throw new \UnexpectedValueException('$error must be array'); - } - - $results[] = new $class($error); - } - - return $results; - } -} diff --git a/src/BaseException.php b/src/BaseException.php index 9522bfa..f200190 100644 --- a/src/BaseException.php +++ b/src/BaseException.php @@ -40,16 +40,31 @@ class BaseException extends \Exception implements BaseExceptionInterface { use HelperTrait; - use ArraySerializerTrait; use TemplateHandlerTrait; /** * @param \Throwable|null $throwable + * @param int $recursion * - * @return array> + * @return array>|null */ - public static function serializeToArray(\Throwable|null $throwable = null): array + public static function serializeToArray(\Throwable|null $throwable = null, int $recursion = 0): array|null { + if($throwable === null) { + return null; + } + + if ($recursion > 8) { + return [ + 'message' => 'Depth of exceptions is greater than 8', + 'code' => 0, + 'source' => self::getSourceFor($throwable), + 'file' => __FILE__, + 'line' => __LINE__, + 'previous' => null, + ]; + } + if ($throwable instanceof BaseExceptionInterface) { return $throwable->toArray(); } @@ -57,8 +72,10 @@ public static function serializeToArray(\Throwable|null $throwable = null): arra return [ 'message' => $throwable->getMessage(), 'code' => $throwable->getCode(), + 'source' => self::getSourceFor($throwable), 'file' => $throwable->getFile(), - 'line' => $throwable->getLine() + 'line' => $throwable->getLine(), + 'previous' => self::serializeToArray($throwable->getPrevious(), $recursion + 1), ]; } @@ -319,7 +336,7 @@ public function getSource(): ?array return $this->source; } - return $this->source = $this->getSourceFor($this); + return $this->source = self::getSourceFor($this); } /** @@ -390,12 +407,13 @@ public function toArray(): array $res = [ 'type' => $previous::class, - 'source' => $this->getSourceFor($previous), + 'source' => self::getSourceFor($previous), 'file' => $this->getFile(), 'line' => $this->getLine(), 'message' => $previous->getMessage(), 'code' => $previous->getCode(), 'data' => [], + 'previous' => self::serializeToArray($previous->getPrevious()), ]; } @@ -420,6 +438,7 @@ public function toArray(): array 'tags' => $this->getTags(), 'code' => $this->getCode(), 'data' => $this->getExceptionData(), + 'previous' => self::serializeToArray($this->getPrevious()) ]; } diff --git a/src/HelperTrait.php b/src/HelperTrait.php index 73067de..d284970 100644 --- a/src/HelperTrait.php +++ b/src/HelperTrait.php @@ -10,7 +10,7 @@ trait HelperTrait * The method defines the source of the exception. * @return array|string */ - final protected function getSourceFor(\Throwable $e, bool $isString = false): array|string + final protected static function getSourceFor(\Throwable $e, bool $isString = false): array|string { $res = $e->getTrace()[0]; diff --git a/src/UnhandledException.php b/src/UnhandledException.php index ca18554..c074341 100644 --- a/src/UnhandledException.php +++ b/src/UnhandledException.php @@ -19,7 +19,7 @@ public function __construct(\Throwable $exception) { parent::__construct([ 'type' => $this->typeInfo($exception), - 'source' => $this->getSourceFor($exception), + 'source' => self::getSourceFor($exception), 'previous' => $exception, ]); } diff --git a/tests/ArraySerializerTraitTest.php b/tests/ArraySerializerTraitTest.php deleted file mode 100644 index 438c08d..0000000 --- a/tests/ArraySerializerTraitTest.php +++ /dev/null @@ -1,169 +0,0 @@ -_errorsToArray( - new BaseException([ - 'message' => 'test message1', - 'code' => 5, - 'exdata' => [2,3,4], - ]) - ); - - $this->assertIsArray($exceptions, '$exceptions must be array'); - $this->assertTrue(\count($exceptions) === 1, '$exceptions must have 1 elements'); - - $res = \array_shift($exceptions); - - $this->assertArrayHasKey('message', $res); - $this->assertArrayHasKey('code', $res); - $this->assertArrayHasKey('data', $res); - $this->assertArrayHasKey('template', $res); - $this->assertArrayHasKey('exdata', $res['data']); - - // several exceptions - $errors = - [ - new BaseException([ - 'message' => 'test message1', - 'code' => 5, - 'exdata' => [2,3,4], - ]), - new LoggableException([ - 'message' => 'test message2', - 'code' => 6, - 'template' => 'this LoggableException with {code}', - 'exdata' => [3,2,1], - ]), - new \Exception('test message3', 7), - new BaseException('test message4', 8), - ]; - - $exceptions = $testedObject->_errorsToArray($errors); - - $this->assertIsArray($exceptions, '$exceptions must be array'); - $this->assertTrue(\count($exceptions) === 4, '$exceptions must have three elements'); - - // 1. - $res = \array_shift($exceptions); - - $this->assertArrayHasKey('message', $res); - $this->assertArrayHasKey('code', $res); - $this->assertArrayHasKey('data', $res); - $this->assertArrayHasKey('template', $res); - - $this->assertEquals('test message1', $res['message']); - $this->assertEquals(5, $res['code']); - $this->assertTrue( - isset($res['data']['exdata']) && - \is_array($res['data']['exdata']) && - \implode('|', $res['data']['exdata']) === '2|3|4', - 'exdata failed' - ); - - // 2. - $res = \array_shift($exceptions); - - $this->assertArrayHasKey('message', $res); - $this->assertArrayHasKey('code', $res); - $this->assertArrayHasKey('data', $res); - $this->assertArrayHasKey('template', $res); - - $this->assertEquals('test message2', $res['message']); - $this->assertEquals('this LoggableException with {code}', $res['template']); - $this->assertEquals(6, $res['code']); - $this->assertTrue( - isset($res['data']['exdata']) && - \is_array($res['data']['exdata']) && - \implode('|', $res['data']['exdata']) === '3|2|1', - 'exdata failed' - ); - - $res = \array_shift($exceptions); - - $this->assertArrayHasKey('message', $res); - $this->assertArrayHasKey('code', $res); - //$this->assertArrayHasKey('data', $res); - - $this->assertEquals('test message3', $res['message']); - $this->assertEquals(7, $res['code']); - - $res = \array_shift($exceptions); - - $this->assertArrayHasKey('message', $res); - $this->assertArrayHasKey('code', $res); - $this->assertArrayHasKey('data', $res); - $this->assertArrayHasKey('template', $res); - - $this->assertEquals('test message4', $res['message']); - $this->assertEquals(8, $res['code']); - } - - public function testArray_to_errors(): void - { - $testedObject = new TestClass(); - - $array = []; - - for ($i = 0; $i < 3; $i++) { - $array[] = - [ - 'message' => 'test message' . ($i + 5), - 'template' => 'test template with {code} and {exdata}', - 'code' => ($i + 10), - 'exdata' => ($i - 10), - ]; - } - - $results = $testedObject->_arrayToErrors($array); - - $i = 0; - - foreach ($results as $exception) { - $this->assertInstanceOf(BaseExceptionInterface::class, $exception); - $this->assertEquals('test template with {code} and {exdata}', $exception->getTemplate()); - $this->assertEquals( - 'test template with ' . ($i + 10) . ' and \'' . ($i - 10) . '\'. test message' . ($i + 5), - $exception->getMessage(), - '$exception->getMessage() failed' - ); - $this->assertEquals(($i + 10), $exception->getCode(), '$exception->getCode() failed'); - $data = $exception->getExceptionData(); - $this->assertIsArray($data, '$exception.data must be array'); - $this->assertArrayHasKey('exdata', $data, '$exception.data.exdata no exists'); - $this->assertEquals(($i - 10), $data['exdata'], '$exception.data.exdata failed'); - - $i++; - } - } - - public function testArray_to_errors_error(): void - { - $testedObject = new TestClass(); - - $this->expectException(\UnexpectedValueException::class); - $this->expectExceptionMessage('$error must be array'); - $testedObject->_arrayToErrors([1,2,3]); - } -} diff --git a/tests/BaseExceptionTest.php b/tests/BaseExceptionTest.php index bc9ed7d..8009ecb 100644 --- a/tests/BaseExceptionTest.php +++ b/tests/BaseExceptionTest.php @@ -236,6 +236,7 @@ public function testToArrayForContainer(): void 'code' => 2, 'data' => [], 'container' => \IfCastle\Exceptions\LoggableException::class, + 'previous' => null, ]; $this->assertIsArray($data, 'data must be array'); @@ -271,6 +272,7 @@ public function testToArrayForContainer2(): void 'code' => 0, 'data' => ['exdata' => $data], 'container' => \IfCastle\Exceptions\LoggableException::class, + 'previous' => null ]; $this->assertIsArray($data, 'data must be array'); @@ -290,6 +292,7 @@ public function testToArrayForTemplate(): void $test = new \ArrayObject([1, 2, 3]); $exception = new \IfCastle\Exceptions\UnexpectedValueType('$test', $test, 'string'); + $line = __LINE__ - 1; $data = $exception->toArray(); @@ -298,10 +301,13 @@ public function testToArrayForTemplate(): void 'type' => UnexpectedValueType::class, 'source' => ['source' => static::class, 'type' => '->', 'function' => 'testToArrayForTemplate'], 'file' => __FILE__, - 'line' => $this->line, + 'line' => $line, 'message' => '', 'template' => 'Unexpected type occurred for the value {name} and type {type}. Expected {expected}', 'code' => 0, + 'data' => ['name' => '$test', 'type' => \ArrayObject::class, 'expected' => 'string'], + 'tags' => [], + 'previous' => null, ]; $this->assertIsArray($data, 'data must be array'); @@ -387,6 +393,7 @@ public function testSerializeToArray(): void $array = BaseException::serializeToArray($baseException); $this->assertArrayHasKey('message', $array, 'message key not found'); + $this->assertArrayHasKey('source', $array, 'source key not found'); $this->assertArrayHasKey('code', $array, 'code key not found'); $this->assertArrayHasKey('file', $array, 'file key not found'); $this->assertArrayHasKey('line', $array, 'line key not found'); @@ -394,6 +401,7 @@ public function testSerializeToArray(): void $array = BaseException::serializeToArray(new \Exception('Some message')); $this->assertArrayHasKey('message', $array, 'message key not found'); + $this->assertArrayHasKey('source', $array, 'source key not found'); $this->assertArrayHasKey('code', $array, 'code key not found'); $this->assertArrayHasKey('file', $array, 'file key not found'); $this->assertArrayHasKey('line', $array, 'line key not found'); diff --git a/tests/HelperTraitTest.php b/tests/HelperTraitTest.php index 77cb8ef..7f61405 100644 --- a/tests/HelperTraitTest.php +++ b/tests/HelperTraitTest.php @@ -21,7 +21,7 @@ public function testGetSourceFor(): void { $testedObject = new TestedClass(); - $result = $testedObject->_getSourceFor(new \Exception('this')); + $result = $testedObject::_getSourceFor(new \Exception('this')); $this->assertEquals( [