From e94b31f3a03edabf6aeee5317aa51475dbcdc90e Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 25 Apr 2015 17:02:32 +0200 Subject: [PATCH] [Debug] PHP7 compatibility with BaseException --- src/Symfony/Component/Debug/ErrorHandler.php | 28 +++++++++--- .../Debug/Exception/FatalBaseException.php | 44 +++++++++++++++++++ .../Debug/Tests/DebugClassLoaderTest.php | 9 +++- .../Debug/Tests/ErrorHandlerTest.php | 4 +- 4 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 src/Symfony/Component/Debug/Exception/FatalBaseException.php diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php index 7720ad9e73..eed05c191f 100644 --- a/src/Symfony/Component/Debug/ErrorHandler.php +++ b/src/Symfony/Component/Debug/ErrorHandler.php @@ -14,6 +14,7 @@ namespace Symfony\Component\Debug; use Psr\Log\LogLevel; use Psr\Log\LoggerInterface; use Symfony\Component\Debug\Exception\ContextErrorException; +use Symfony\Component\Debug\Exception\FatalBaseException; use Symfony\Component\Debug\Exception\FatalErrorException; use Symfony\Component\Debug\Exception\OutOfMemoryException; use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler; @@ -430,22 +431,34 @@ class ErrorHandler /** * Handles an exception by logging then forwarding it to an other handler. * - * @param \Exception $exception An exception to handle - * @param array $error An array as returned by error_get_last() + * @param \Exception|\BaseException $exception An exception to handle + * @param array $error An array as returned by error_get_last() * * @internal */ - public function handleException(\Exception $exception, array $error = null) + public function handleException($exception, array $error = null) { - if ($this->loggedErrors & E_ERROR) { + if (!$exception instanceof \Exception) { + $exception = new FatalBaseException($exception); + } + $type = $exception instanceof FatalErrorException ? $exception->getSeverity() : E_ERROR; + + if ($this->loggedErrors & $type) { $e = array( - 'type' => E_ERROR, + 'type' => $type, 'file' => $exception->getFile(), 'line' => $exception->getLine(), 'level' => error_reporting(), 'stack' => $exception->getTrace(), ); - if ($exception instanceof FatalErrorException) { + if ($exception instanceof FatalBaseException) { + $error = array( + 'type' => $type, + 'message' => $message = $exception->getMessage(), + 'file' => $e['file'], + 'line' => $e['line'], + ); + } elseif ($exception instanceof FatalErrorException) { $message = 'Fatal '.$exception->getMessage(); } elseif ($exception instanceof \ErrorException) { $message = 'Uncaught '.$exception->getMessage(); @@ -475,6 +488,9 @@ class ErrorHandler } catch (\Exception $handlerException) { $this->exceptionHandler = null; $this->handleException($handlerException); + } catch (\BaseException $handlerException) { + $this->exceptionHandler = null; + $this->handleException($handlerException); } } diff --git a/src/Symfony/Component/Debug/Exception/FatalBaseException.php b/src/Symfony/Component/Debug/Exception/FatalBaseException.php new file mode 100644 index 0000000000..769d30ccb1 --- /dev/null +++ b/src/Symfony/Component/Debug/Exception/FatalBaseException.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Exception; + +/** + * Base Fatal Error Exception. + * + * @author Nicolas Grekas + */ +class FatalBaseException extends FatalErrorException +{ + public function __construct(\BaseException $e) + { + if ($e instanceof \ParseException) { + $message = 'Parse error: '.$e->getMessage(); + $severity = E_PARSE; + } elseif ($e instanceof \TypeException) { + $message = 'Type error: '.$e->getMessage(); + $severity = E_RECOVERABLE_ERROR; + } else { + $message = 'Fatal error: '.$e->getMessage(); + $severity = E_ERROR; + } + + \ErrorException::__construct( + $message, + $e->getCode(), + $severity, + $e->getFile(), + $e->getLine() + ); + + $this->setTrace($e->getTrace()); + } +} diff --git a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php index efa5d14cc2..169f4210ed 100644 --- a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php +++ b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php @@ -104,9 +104,14 @@ class DebugClassLoaderTest extends \PHPUnit_Framework_TestCase // if an exception is thrown, the test passed restore_error_handler(); restore_exception_handler(); - $this->assertEquals(E_STRICT, $exception->getSeverity()); $this->assertStringStartsWith(__FILE__, $exception->getFile()); - $this->assertRegexp('/^Runtime Notice: Declaration/', $exception->getMessage()); + if (PHP_VERSION_ID < 70000) { + $this->assertRegexp('/^Runtime Notice: Declaration/', $exception->getMessage()); + $this->assertEquals(E_STRICT, $exception->getSeverity()); + } else { + $this->assertRegexp('/^Warning: Declaration/', $exception->getMessage()); + $this->assertEquals(E_WARNING, $exception->getSeverity()); + } } catch (\Exception $exception) { restore_error_handler(); restore_exception_handler(); diff --git a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php index 0f52680370..1b3f7b41ed 100644 --- a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php +++ b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php @@ -336,7 +336,7 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase $logArgCheck = function ($level, $message, $context) use ($that) { $that->assertEquals('Fatal Parse Error: foo', $message); $that->assertArrayHasKey('type', $context); - $that->assertEquals($context['type'], E_ERROR); + $that->assertEquals($context['type'], E_PARSE); }; $logger @@ -345,7 +345,7 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase ->will($this->returnCallback($logArgCheck)) ; - $handler->setDefaultLogger($logger, E_ERROR); + $handler->setDefaultLogger($logger, E_PARSE); $handler->handleFatalError($error);