From 64d02cb350c41ca4dba924a598eb55cbf3ce166c Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Wed, 29 May 2019 16:52:34 +0200 Subject: [PATCH] [Debug] Make ExceptionHandler and ErrorHandler final --- .../ErrorCatcher/ExceptionHandler.php | 7 +- .../Tests/ExceptionHandlerTest.php | 79 ++++++++++++++----- .../Tests/MockExceptionHandler.php | 24 ------ 3 files changed, 66 insertions(+), 44 deletions(-) delete mode 100644 src/Symfony/Component/ErrorCatcher/Tests/MockExceptionHandler.php diff --git a/src/Symfony/Component/ErrorCatcher/ExceptionHandler.php b/src/Symfony/Component/ErrorCatcher/ExceptionHandler.php index 225db00622e0c..0207472c17b06 100644 --- a/src/Symfony/Component/ErrorCatcher/ExceptionHandler.php +++ b/src/Symfony/Component/ErrorCatcher/ExceptionHandler.php @@ -12,6 +12,7 @@ namespace Symfony\Component\ErrorCatcher; use Symfony\Component\ErrorCatcher\ErrorRenderer\HtmlErrorRenderer; +use Symfony\Component\ErrorCatcher\Exception\FatalThrowableError; use Symfony\Component\ErrorCatcher\Exception\FlattenException; use Symfony\Component\ErrorCatcher\Exception\OutOfMemoryException; use Symfony\Component\HttpKernel\Debug\FileLinkFormatter; @@ -101,8 +102,12 @@ public function setHandler(callable $handler = null) * The latter takes precedence and any output from the former is cancelled, * if and only if nothing bad happens in this handling path. */ - public function handle(\Exception $exception) + public function handle(\Throwable $exception) { + if (!$exception instanceof \Exception) { + $exception = new FatalThrowableError($exception); + } + if (null === $this->handler || $exception instanceof OutOfMemoryException) { $this->sendPhpResponse($exception); diff --git a/src/Symfony/Component/ErrorCatcher/Tests/ExceptionHandlerTest.php b/src/Symfony/Component/ErrorCatcher/Tests/ExceptionHandlerTest.php index d3b8deec80c4d..12c8513b54399 100644 --- a/src/Symfony/Component/ErrorCatcher/Tests/ExceptionHandlerTest.php +++ b/src/Symfony/Component/ErrorCatcher/Tests/ExceptionHandlerTest.php @@ -85,7 +85,7 @@ public function testHeaders() ob_start(); $handler->sendPhpResponse(new MethodNotAllowedHttpException(['POST'])); - $response = ob_get_clean(); + ob_get_clean(); $expectedHeaders = [ ['HTTP/1.0 405', true, null], @@ -106,37 +106,78 @@ public function testNestedExceptions() $this->assertStringMatchesFormat('%A

Foo

%A

Bar

%A', $response); } - public function testHandle() + /** + * @dataProvider handleProvider + */ + public function testHandle(\Throwable $exception, string $expectedClass, string $expectedTitle, string $expectedMessage) { - $exception = new \Exception('foo'); - - $handler = $this->getMockBuilder('Symfony\Component\ErrorCatcher\ExceptionHandler')->setMethods(['sendPhpResponse'])->getMock(); - $handler - ->expects($this->exactly(2)) - ->method('sendPhpResponse'); + $handler = new ExceptionHandler(true); + ob_start(); $handler->handle($exception); - $handler->setHandler(function ($e) use ($exception) { - $this->assertSame($exception, $e); + $this->assertThatTheExceptionWasOutput(ob_get_clean(), $expectedClass, $expectedTitle, $expectedMessage); + } + + public function handleProvider() + { + return [ + [new \Exception('foo'), \Exception::class, 'Exception', 'foo'], + [new \Error('bar'), \Error::class, 'Error', 'bar'], + ]; + } + + public function testHandleWithACustomHandlerThatOutputsSomething() + { + $handler = new ExceptionHandler(true); + ob_start(); + $handler->setHandler(function () { + echo 'ccc'; }); - $handler->handle($exception); + $handler->handle(new \Exception()); + ob_end_flush(); // Necessary because of this PHP bug : https://bugs.php.net/bug.php?id=76563 + $this->assertSame('ccc', ob_get_clean()); } - public function testHandleOutOfMemoryException() + public function testHandleWithACustomHandlerThatOutputsNothing() + { + $handler = new ExceptionHandler(true); + $handler->setHandler(function () {}); + + $handler->handle(new \Exception('ccc')); + + $this->assertThatTheExceptionWasOutput(ob_get_clean(), \Exception::class, 'Exception', 'ccc'); + } + + public function testHandleWithACustomHandlerThatFails() { - $exception = new OutOfMemoryException('foo', 0, E_ERROR, __FILE__, __LINE__); + $handler = new ExceptionHandler(true); + $handler->setHandler(function () { + throw new \RuntimeException(); + }); + + $handler->handle(new \Exception('ccc')); - $handler = $this->getMockBuilder('Symfony\Component\ErrorCatcher\ExceptionHandler')->setMethods(['sendPhpResponse'])->getMock(); - $handler - ->expects($this->once()) - ->method('sendPhpResponse'); + $this->assertThatTheExceptionWasOutput(ob_get_clean(), \Exception::class, 'Exception', 'ccc'); + } - $handler->setHandler(function ($e) { + public function testHandleOutOfMemoryException() + { + $handler = new ExceptionHandler(true); + ob_start(); + $handler->setHandler(function () { $this->fail('OutOfMemoryException should bypass the handler'); }); - $handler->handle($exception); + $handler->handle(new OutOfMemoryException('foo', 0, E_ERROR, __FILE__, __LINE__)); + + $this->assertThatTheExceptionWasOutput(ob_get_clean(), OutOfMemoryException::class, 'OutOfMemoryException', 'foo'); + } + + private function assertThatTheExceptionWasOutput(string $content, string $expectedClass, string $expectedTitle, string $expectedMessage) + { + $this->assertContains(sprintf('%s', $expectedClass, $expectedTitle), $content); + $this->assertContains(sprintf('

%s

', $expectedMessage), $content); } } diff --git a/src/Symfony/Component/ErrorCatcher/Tests/MockExceptionHandler.php b/src/Symfony/Component/ErrorCatcher/Tests/MockExceptionHandler.php deleted file mode 100644 index b09f9a7497132..0000000000000 --- a/src/Symfony/Component/ErrorCatcher/Tests/MockExceptionHandler.php +++ /dev/null @@ -1,24 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\ErrorCatcher\Tests; - -use Symfony\Component\ErrorCatcher\ExceptionHandler; - -class MockExceptionHandler extends ExceptionHandler -{ - public $e; - - public function handle(\Exception $e) - { - $this->e = $e; - } -}