bug #17052 [2.7] Fixed flatten exception recursion with errors (GrahamCampbell)

This PR was submitted for the 2.7 branch but it was merged into the 2.3 branch instead (closes #17052).

Discussion
----------

[2.7] Fixed flatten exception recursion with errors

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | N/A
| License       | MIT
| Doc PR        | N/A

Consider the following code:

```php
$error = new ParseError();

$exception = new RuntimeException($error->getMessage(), $error->getCode(), $error);

$flat = new Symfony\Component\Debug\Exception\FlattenException($exception);
```

Without this fix, that code is broken.

You'll end up with something like this:

```
FatalThrowableError in FlattenException.php line 76:
Type error: Argument 1 passed to Symfony\Component\Debug\Exception\FlattenException::create() must be an instance of Exception, instance of ParseError given
```

---

I came across this error issue in https://github.com/laravel/framework/issues/11329.

Commits
-------

2b0721d [2.7] Fixed flatten exception recursion with errors
This commit is contained in:
Fabien Potencier 2015-12-26 13:17:23 +01:00
commit af3f4eaa2b
2 changed files with 21 additions and 2 deletions

View File

@ -94,8 +94,13 @@ class FlattenException extends LegacyFlattenException
$e->setClass(get_class($exception));
$e->setFile($exception->getFile());
$e->setLine($exception->getLine());
if ($exception->getPrevious()) {
$e->setPrevious(static::create($exception->getPrevious()));
$previous = $exception->getPrevious();
if ($previous instanceof \Exception) {
$e->setPrevious(static::create($previous));
} elseif ($previous instanceof \Throwable) {
$e->setPrevious(static::create(new FatalThrowableError($previous)));
}
return $e;

View File

@ -131,6 +131,20 @@ class FlattenExceptionTest extends \PHPUnit_Framework_TestCase
$this->assertSame(array($flattened2), $flattened->getAllPrevious());
}
/**
* @requires PHP 7.0
*/
public function testPreviousError()
{
$exception = new \Exception('test', 123, new \ParseError('Oh noes!', 42));
$flattened = FlattenException::create($exception)->getPrevious();
$this->assertEquals($flattened->getMessage(), 'Parse error: Oh noes!', 'The message is copied from the original exception.');
$this->assertEquals($flattened->getCode(), 42, 'The code is copied from the original exception.');
$this->assertEquals($flattened->getClass(), 'Symfony\Component\Debug\Exception\FatalThrowableError', 'The class is set to the class of the original exception');
}
/**
* @dataProvider flattenDataProvider
*/