From 96c1a6fa71e18fb8c7944efe587202292abb27f8 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Wed, 14 Mar 2018 14:16:39 +0100 Subject: [PATCH] Support any Throwable object in FlattenException. --- .../Debug/Exception/FlattenException.php | 27 ++++++--- .../Tests/Exception/FlattenExceptionTest.php | 60 ++++++++++++++----- 2 files changed, 65 insertions(+), 22 deletions(-) diff --git a/src/Symfony/Component/Debug/Exception/FlattenException.php b/src/Symfony/Component/Debug/Exception/FlattenException.php index aa6e47333b..f70085160b 100644 --- a/src/Symfony/Component/Debug/Exception/FlattenException.php +++ b/src/Symfony/Component/Debug/Exception/FlattenException.php @@ -15,7 +15,7 @@ use Symfony\Component\HttpFoundation\Exception\RequestExceptionInterface; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; /** - * FlattenException wraps a PHP Exception to be able to serialize it. + * FlattenException wraps a PHP Error or Exception to be able to serialize it. * * Basically, this class removes all objects from the trace. * @@ -34,6 +34,11 @@ class FlattenException private $line; public static function create(\Exception $exception, $statusCode = null, array $headers = array()) + { + return static::createFromThrowable($exception, $statusCode, $headers); + } + + public static function createFromThrowable(\Throwable $exception, ?int $statusCode = null, array $headers = array()): self { $e = new static(); $e->setMessage($exception->getMessage()); @@ -52,17 +57,15 @@ class FlattenException $e->setStatusCode($statusCode); $e->setHeaders($headers); - $e->setTraceFromException($exception); + $e->setTraceFromThrowable($exception); $e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : \get_class($exception)); $e->setFile($exception->getFile()); $e->setLine($exception->getLine()); $previous = $exception->getPrevious(); - if ($previous instanceof \Exception) { - $e->setPrevious(static::create($previous)); - } elseif ($previous instanceof \Throwable) { - $e->setPrevious(static::create(new FatalThrowableError($previous))); + if ($previous instanceof \Throwable) { + $e->setPrevious(static::createFromThrowable($previous)); } return $e; @@ -178,9 +181,19 @@ class FlattenException return $this->trace; } + /** + * @deprecated since 4.1, use {@see setTraceFromThrowable()} instead. + */ public function setTraceFromException(\Exception $exception) { - $this->setTrace($exception->getTrace(), $exception->getFile(), $exception->getLine()); + @trigger_error(sprintf('"%s" is deprecated since Symfony 4.1, use "setTraceFromThrowable()" instead.', __METHOD__), E_USER_DEPRECATED); + + $this->setTraceFromThrowable($exception); + } + + public function setTraceFromThrowable(\Throwable $throwable): void + { + $this->setTrace($throwable->getTrace(), $throwable->getFile(), $throwable->getLine()); } public function setTrace($trace, $file, $line) diff --git a/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php b/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php index 6c9b7f2138..8b6f77b2f8 100644 --- a/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php +++ b/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php @@ -40,6 +40,12 @@ class FlattenExceptionTest extends TestCase $flattened = FlattenException::create(new \RuntimeException()); $this->assertEquals('500', $flattened->getStatusCode()); + $flattened = FlattenException::createFromThrowable(new \DivisionByZeroError(), 403); + $this->assertEquals('403', $flattened->getStatusCode()); + + $flattened = FlattenException::createFromThrowable(new \DivisionByZeroError()); + $this->assertEquals('500', $flattened->getStatusCode()); + $flattened = FlattenException::create(new NotFoundHttpException()); $this->assertEquals('404', $flattened->getStatusCode()); @@ -112,10 +118,10 @@ class FlattenExceptionTest extends TestCase /** * @dataProvider flattenDataProvider */ - public function testFlattenHttpException(\Exception $exception) + public function testFlattenHttpException(\Throwable $exception) { - $flattened = FlattenException::create($exception); - $flattened2 = FlattenException::create($exception); + $flattened = FlattenException::createFromThrowable($exception); + $flattened2 = FlattenException::createFromThrowable($exception); $flattened->setPrevious($flattened2); @@ -124,7 +130,7 @@ class FlattenExceptionTest extends TestCase $this->assertInstanceOf($flattened->getClass(), $exception, 'The class is set to the class of the original exception'); } - public function testThrowable() + public function testWrappedThrowable() { $exception = new FatalThrowableError(new \DivisionByZeroError('Ouch', 42)); $flattened = FlattenException::create($exception); @@ -134,13 +140,23 @@ class FlattenExceptionTest extends TestCase $this->assertSame('DivisionByZeroError', $flattened->getClass(), 'The class is set to the class of the original error'); } + public function testThrowable() + { + $error = new \DivisionByZeroError('Ouch', 42); + $flattened = FlattenException::createFromThrowable($error); + + $this->assertSame('Ouch', $flattened->getMessage(), 'The message is copied from the original error.'); + $this->assertSame(42, $flattened->getCode(), 'The code is copied from the original error.'); + $this->assertSame('DivisionByZeroError', $flattened->getClass(), 'The class is set to the class of the original error'); + } + /** * @dataProvider flattenDataProvider */ - public function testPrevious(\Exception $exception) + public function testPrevious(\Throwable $exception) { - $flattened = FlattenException::create($exception); - $flattened2 = FlattenException::create($exception); + $flattened = FlattenException::createFromThrowable($exception); + $flattened2 = FlattenException::createFromThrowable($exception); $flattened->setPrevious($flattened2); @@ -163,33 +179,33 @@ class FlattenExceptionTest extends TestCase /** * @dataProvider flattenDataProvider */ - public function testLine(\Exception $exception) + public function testLine(\Throwable $exception) { - $flattened = FlattenException::create($exception); + $flattened = FlattenException::createFromThrowable($exception); $this->assertSame($exception->getLine(), $flattened->getLine()); } /** * @dataProvider flattenDataProvider */ - public function testFile(\Exception $exception) + public function testFile(\Throwable $exception) { - $flattened = FlattenException::create($exception); + $flattened = FlattenException::createFromThrowable($exception); $this->assertSame($exception->getFile(), $flattened->getFile()); } /** * @dataProvider flattenDataProvider */ - public function testToArray(\Exception $exception) + public function testToArray(\Throwable $exception, string $expectedClass) { - $flattened = FlattenException::create($exception); + $flattened = FlattenException::createFromThrowable($exception); $flattened->setTrace(array(), 'foo.php', 123); $this->assertEquals(array( array( 'message' => 'test', - 'class' => 'Exception', + 'class' => $expectedClass, 'trace' => array(array( 'namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => '', 'file' => 'foo.php', 'line' => 123, 'args' => array(), @@ -198,10 +214,24 @@ class FlattenExceptionTest extends TestCase ), $flattened->toArray()); } + public function testCreate() + { + $exception = new NotFoundHttpException( + 'test', + new \RuntimeException('previous', 123) + ); + + $this->assertSame( + FlattenException::createFromThrowable($exception)->toArray(), + FlattenException::create($exception)->toArray() + ); + } + public function flattenDataProvider() { return array( - array(new \Exception('test', 123)), + array(new \Exception('test', 123), 'Exception'), + array(new \Error('test', 123), 'Error'), ); }