From b0320967633d5571e211aa80d19e7050a001e096 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 28 Mar 2016 11:08:12 +0200 Subject: [PATCH] [Debug] Fix handling of php7 throwables --- src/Symfony/Component/Debug/Debug.php | 24 ++++++++++++++++++++ src/Symfony/Component/Debug/ErrorHandler.php | 6 +++++ 2 files changed, 30 insertions(+) diff --git a/src/Symfony/Component/Debug/Debug.php b/src/Symfony/Component/Debug/Debug.php index 82014e4ad42a1..eca19da9e66ec 100644 --- a/src/Symfony/Component/Debug/Debug.php +++ b/src/Symfony/Component/Debug/Debug.php @@ -46,6 +46,30 @@ public static function enable($errorReportingLevel = null, $displayErrors = true ErrorHandler::register($errorReportingLevel, $displayErrors); if ('cli' !== PHP_SAPI) { ExceptionHandler::register(); + + if (PHP_VERSION_ID >= 70000) { + $exceptionHandler = set_exception_handler(function ($throwable) use (&$exceptionHandler) { + if ($throwable instanceof \Exception) { + $exception = $throwable; + } else { + static $refl = null; + + if (null === $refl) { + $refl = array(); + foreach (array('file', 'line', 'trace') as $prop) { + $prop = new \ReflectionProperty('Exception', $prop); + $prop->setAccessible(true); + $refl[] = $prop; + } + } + $exception = new \Exception($throwable->getMessage(), $throwable->getCode()); + foreach ($refl as $prop) { + $prop->setValue($exception, $throwable->{'get'.$prop->name}()); + } + } + $exceptionHandler($exception); + }); + } // CLI - display errors only if they're not already logged to STDERR } elseif ($displayErrors && (!ini_get('log_errors') || ini_get('error_log'))) { ini_set('display_errors', 1); diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php index 43e196242a7e1..f12ece7a0d101 100644 --- a/src/Symfony/Component/Debug/ErrorHandler.php +++ b/src/Symfony/Component/Debug/ErrorHandler.php @@ -197,6 +197,12 @@ public function handleFatal() $exceptionHandler = set_exception_handler(function () {}); restore_exception_handler(); + if (PHP_VERSION_ID >= 70000 && $exceptionHandler instanceof \Closure) { + $reflector = new \ReflectionFunction($exceptionHandler); + foreach ($reflector->getStaticVariables() as $exceptionHandler) { + break; + } + } if (is_array($exceptionHandler) && $exceptionHandler[0] instanceof ExceptionHandler) { $level = isset($this->levels[$type]) ? $this->levels[$type] : $type; $message = sprintf('%s: %s in %s line %d', $level, $error['message'], $error['file'], $error['line']);