feature #26528 [Debug] Support any Throwable object in FlattenException (derrabus)
This PR was merged into the 4.1-dev branch.
Discussion
----------
[Debug] Support any Throwable object in FlattenException
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | yes
| Tests pass? | yes
| Fixed tickets | #26429
| License | MIT
| Doc PR | N/A
Alternative to #26447 without BC breaks, follows #26028.
This PR removes the need to convert `Throwable` objects into exceptions when working with `FlattenException`.
ping @instabledesign @ostrolucky @nicolas-grekas
Commits
-------
96c1a6fa71
Support any Throwable object in FlattenException.
This commit is contained in:
commit
47e2bd31da
@ -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)
|
||||
|
@ -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'),
|
||||
);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user