From 15ef182b9971472aa30753da6349c0d28f477d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Thu, 2 Apr 2015 14:57:42 +0200 Subject: [PATCH] [Debug] Made code in ErrorHandler easier to read --- src/Symfony/Component/Debug/ErrorHandler.php | 162 ++++++++++--------- 1 file changed, 84 insertions(+), 78 deletions(-) diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php index 48e4a2d69e..280d5f8abc 100644 --- a/src/Symfony/Component/Debug/ErrorHandler.php +++ b/src/Symfony/Component/Debug/ErrorHandler.php @@ -356,69 +356,71 @@ class ErrorHandler $throw = $this->thrownErrors & $type & $level; $type &= $level | $this->screamedErrors; - if ($type && ($log || $throw)) { - if (PHP_VERSION_ID < 50400 && isset($context['GLOBALS']) && ($this->scopedErrors & $type)) { - $e = $context; // Whatever the signature of the method, - unset($e['GLOBALS'], $context); // $context is always a reference in 5.3 - $context = $e; - } + if (!$type || (!$log && !$throw)) { + return $type && $log; + } - if ($throw) { - if (($this->scopedErrors & $type) && class_exists('Symfony\Component\Debug\Exception\ContextErrorException')) { - // Checking for class existence is a work around for https://bugs.php.net/42098 - $throw = new ContextErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line, $context); - } else { - $throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line); - } + if (PHP_VERSION_ID < 50400 && isset($context['GLOBALS']) && ($this->scopedErrors & $type)) { + $e = $context; // Whatever the signature of the method, + unset($e['GLOBALS'], $context); // $context is always a reference in 5.3 + $context = $e; + } - if (PHP_VERSION_ID <= 50407 && (PHP_VERSION_ID >= 50400 || PHP_VERSION_ID <= 50317)) { - // Exceptions thrown from error handlers are sometimes not caught by the exception - // handler and shutdown handlers are bypassed before 5.4.8/5.3.18. - // We temporarily re-enable display_errors to prevent any blank page related to this bug. - - $throw->errorHandlerCanary = new ErrorHandlerCanary(); - } - - throw $throw; - } - - // For duplicated errors, log the trace only once - $e = md5("{$type}/{$line}/{$file}\x00{$message}", true); - $trace = true; - - if (!($this->tracedErrors & $type) || isset($this->loggedTraces[$e])) { - $trace = false; + if ($throw) { + if (($this->scopedErrors & $type) && class_exists('Symfony\Component\Debug\Exception\ContextErrorException')) { + // Checking for class existence is a work around for https://bugs.php.net/42098 + $throw = new ContextErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line, $context); } else { - $this->loggedTraces[$e] = 1; + $throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line); } - $e = compact('type', 'file', 'line', 'level'); + if (PHP_VERSION_ID <= 50407 && (PHP_VERSION_ID >= 50400 || PHP_VERSION_ID <= 50317)) { + // Exceptions thrown from error handlers are sometimes not caught by the exception + // handler and shutdown handlers are bypassed before 5.4.8/5.3.18. + // We temporarily re-enable display_errors to prevent any blank page related to this bug. - if ($type & $level) { - if ($this->scopedErrors & $type) { - $e['context'] = $context; - if ($trace) { - $e['stack'] = debug_backtrace(true); // Provide object - } - } elseif ($trace) { - $e['stack'] = debug_backtrace(PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : false); - } + $throw->errorHandlerCanary = new ErrorHandlerCanary(); } - if ($this->isRecursive) { - $log = 0; - } elseif (self::$stackedErrorLevels) { - self::$stackedErrors[] = array($this->loggers[$type], $message, $e); - } else { - try { - $this->isRecursive = true; - $this->loggers[$type][0]->log($this->loggers[$type][1], $message, $e); - $this->isRecursive = false; - } catch (\Exception $e) { - $this->isRecursive = false; + throw $throw; + } - throw $e; + // For duplicated errors, log the trace only once + $e = md5("{$type}/{$line}/{$file}\x00{$message}", true); + $trace = true; + + if (!($this->tracedErrors & $type) || isset($this->loggedTraces[$e])) { + $trace = false; + } else { + $this->loggedTraces[$e] = 1; + } + + $e = compact('type', 'file', 'line', 'level'); + + if ($type & $level) { + if ($this->scopedErrors & $type) { + $e['context'] = $context; + if ($trace) { + $e['stack'] = debug_backtrace(true); // Provide object } + } elseif ($trace) { + $e['stack'] = debug_backtrace(PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : false); + } + } + + if ($this->isRecursive) { + $log = 0; + } elseif (self::$stackedErrorLevels) { + self::$stackedErrors[] = array($this->loggers[$type], $message, $e); + } else { + try { + $this->isRecursive = true; + $this->loggers[$type][0]->log($this->loggers[$type][1], $message, $e); + $this->isRecursive = false; + } catch (\Exception $e) { + $this->isRecursive = false; + + throw $e; } } @@ -487,40 +489,44 @@ class ErrorHandler public static function handleFatalError(array $error = null) { self::$reservedMemory = ''; + $handler = set_error_handler('var_dump', 0); $handler = is_array($handler) ? $handler[0] : null; restore_error_handler(); - if ($handler instanceof self) { - if (null === $error) { - $error = error_get_last(); - } - try { - while (self::$stackedErrorLevels) { - static::unstackErrors(); - } - } catch (\Exception $exception) { - // Handled below - } + if (!$handler instanceof self) { + return; + } - if ($error && ($error['type'] & (E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR))) { - // Let's not throw anymore but keep logging - $handler->throwAt(0, true); + if (null === $error) { + $error = error_get_last(); + } - if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) { - $exception = new OutOfMemoryException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, false); - } else { - $exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true); - } - } elseif (!isset($exception)) { - return; + try { + while (self::$stackedErrorLevels) { + static::unstackErrors(); } + } catch (\Exception $exception) { + // Handled below + } - try { - $handler->handleException($exception, $error); - } catch (FatalErrorException $e) { - // Ignore this re-throw + if ($error && ($error['type'] & (E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR))) { + // Let's not throw anymore but keep logging + $handler->throwAt(0, true); + + if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) { + $exception = new OutOfMemoryException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, false); + } else { + $exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true); } + } elseif (!isset($exception)) { + return; + } + + try { + $handler->handleException($exception, $error); + } catch (FatalErrorException $e) { + // Ignore this re-throw } }