mirror of
https://github.com/symfony/debug.git
synced 2026-03-25 09:42:20 +01:00
Compare commits
69 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a26ddce7fe | ||
|
|
5d48e9c0f8 | ||
|
|
fe8838e11c | ||
|
|
fc4afe37fd | ||
|
|
4486d2be5e | ||
|
|
e191af723b | ||
|
|
ce92aa6388 | ||
|
|
7e7619ce57 | ||
|
|
b74e4e0899 | ||
|
|
5555d0c0c4 | ||
|
|
0a614d393b | ||
|
|
f693ba8818 | ||
|
|
6a76089f75 | ||
|
|
338c06c0dc | ||
|
|
7d96be3eaf | ||
|
|
0d52d1c98c | ||
|
|
a91a8fdd8c | ||
|
|
35e36287fc | ||
|
|
bc9e38887a | ||
|
|
b1babdd3a2 | ||
|
|
955cfa5e94 | ||
|
|
05e858fda6 | ||
|
|
253f4fd5f6 | ||
|
|
546db6f2bf | ||
|
|
ff9e8cb401 | ||
|
|
e46133c70d | ||
|
|
c617cfc32e | ||
|
|
526150f1a8 | ||
|
|
5f44cab999 | ||
|
|
79c3d84f0b | ||
|
|
22c18d44e7 | ||
|
|
79b7f987a6 | ||
|
|
12370d9f98 | ||
|
|
0972e3f262 | ||
|
|
177a0b9b35 | ||
|
|
4f43301e60 | ||
|
|
1086f33dba | ||
|
|
7f065aa0af | ||
|
|
d0cddb9f2a | ||
|
|
c573a9f2a1 | ||
|
|
e72a0340dc | ||
|
|
38fdc933c7 | ||
|
|
a0a29e9867 | ||
|
|
271c75c24d | ||
|
|
08bf2c53db | ||
|
|
f0546da70c | ||
|
|
d295479508 | ||
|
|
d2d11379b5 | ||
|
|
eaaec993ca | ||
|
|
e12a6f1168 | ||
|
|
34d945c4eb | ||
|
|
2827a6e8c2 | ||
|
|
9c5b622f5a | ||
|
|
efc9656dcb | ||
|
|
f45a908634 | ||
|
|
236ca98a42 | ||
|
|
0946243775 | ||
|
|
e1ce6a4ded | ||
|
|
8470d77011 | ||
|
|
2662c21dea | ||
|
|
344f50ce82 | ||
|
|
28590cbb8f | ||
|
|
f74c05b0b5 | ||
|
|
102a9b2776 | ||
|
|
58552db096 | ||
|
|
f302a96911 | ||
|
|
25f994cdf8 | ||
|
|
e90099a295 | ||
|
|
ae2d80df72 |
@@ -23,10 +23,7 @@ class Debug
|
||||
/**
|
||||
* Enables the debug tools.
|
||||
*
|
||||
* This method registers an error handler and an exception handler.
|
||||
*
|
||||
* If the Symfony ClassLoader component is available, a special
|
||||
* class loader is also registered.
|
||||
* This method registers an error handler, an exception handler and a special class loader.
|
||||
*
|
||||
* @param int $errorReportingLevel The level of error reporting you want
|
||||
* @param bool $displayErrors Whether to display errors (for development) or just log them (for production)
|
||||
@@ -45,7 +42,7 @@ class Debug
|
||||
error_reporting(-1);
|
||||
}
|
||||
|
||||
if ('cli' !== PHP_SAPI) {
|
||||
if (!\in_array(PHP_SAPI, array('cli', 'phpdbg'), true)) {
|
||||
ini_set('display_errors', 0);
|
||||
ExceptionHandler::register();
|
||||
} elseif ($displayErrors && (!ini_get('log_errors') || ini_get('error_log'))) {
|
||||
|
||||
@@ -26,6 +26,7 @@ class DebugClassLoader
|
||||
{
|
||||
private $classLoader;
|
||||
private $isFinder;
|
||||
private $loaded = array();
|
||||
private $wasFinder;
|
||||
private static $caseCheck;
|
||||
private static $deprecated = array();
|
||||
@@ -33,8 +34,6 @@ class DebugClassLoader
|
||||
private static $darwinCache = array('/' => array('/', array()));
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param callable|object $classLoader Passing an object is @deprecated since version 2.5 and support for it will be removed in 3.0
|
||||
*/
|
||||
public function __construct($classLoader)
|
||||
@@ -143,7 +142,7 @@ class DebugClassLoader
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
|
||||
if ($this->wasFinder) {
|
||||
return $this->classLoader[0]->findFile($class);
|
||||
@@ -164,9 +163,10 @@ class DebugClassLoader
|
||||
ErrorHandler::stackErrors();
|
||||
|
||||
try {
|
||||
if ($this->isFinder) {
|
||||
if ($this->isFinder && !isset($this->loaded[$class])) {
|
||||
$this->loaded[$class] = true;
|
||||
if ($file = $this->classLoader[0]->findFile($class)) {
|
||||
require_once $file;
|
||||
require $file;
|
||||
}
|
||||
} else {
|
||||
call_user_func($this->classLoader, $class);
|
||||
@@ -186,7 +186,7 @@ class DebugClassLoader
|
||||
|
||||
$exists = class_exists($class, false) || interface_exists($class, false) || (function_exists('trait_exists') && trait_exists($class, false));
|
||||
|
||||
if ('\\' === $class[0]) {
|
||||
if ($class && '\\' === $class[0]) {
|
||||
$class = substr($class, 1);
|
||||
}
|
||||
|
||||
@@ -203,18 +203,11 @@ class DebugClassLoader
|
||||
} elseif (preg_match('#\n \* @deprecated (.*?)\r?\n \*(?: @|/$)#s', $refl->getDocComment(), $notice)) {
|
||||
self::$deprecated[$name] = preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]);
|
||||
} else {
|
||||
if (2 > $len = 1 + (strpos($name, '\\', 1 + strpos($name, '\\')) ?: strpos($name, '_'))) {
|
||||
if (2 > $len = 1 + (strpos($name, '\\') ?: strpos($name, '_'))) {
|
||||
$len = 0;
|
||||
$ns = '';
|
||||
} else {
|
||||
switch ($ns = substr($name, 0, $len)) {
|
||||
case 'Symfony\Bridge\\':
|
||||
case 'Symfony\Bundle\\':
|
||||
case 'Symfony\Component\\':
|
||||
$ns = 'Symfony\\';
|
||||
$len = strlen($ns);
|
||||
break;
|
||||
}
|
||||
$ns = substr($name, 0, $len);
|
||||
}
|
||||
$parent = get_parent_class($class);
|
||||
|
||||
|
||||
110
ErrorHandler.php
110
ErrorHandler.php
@@ -103,6 +103,7 @@ class ErrorHandler
|
||||
private static $stackedErrors = array();
|
||||
private static $stackedErrorLevels = array();
|
||||
private static $toStringException = null;
|
||||
private static $exitCode = 0;
|
||||
|
||||
/**
|
||||
* Same init value as thrownErrors.
|
||||
@@ -148,10 +149,24 @@ class ErrorHandler
|
||||
$handler = $prev[0];
|
||||
$replace = false;
|
||||
}
|
||||
if ($replace || !$prev) {
|
||||
$handler->setExceptionHandler(set_exception_handler(array($handler, 'handleException')));
|
||||
} else {
|
||||
if (!$replace && $prev) {
|
||||
restore_error_handler();
|
||||
$handlerIsRegistered = is_array($prev) && $handler === $prev[0];
|
||||
} else {
|
||||
$handlerIsRegistered = true;
|
||||
}
|
||||
if (is_array($prev = set_exception_handler(array($handler, 'handleException'))) && $prev[0] instanceof self) {
|
||||
restore_exception_handler();
|
||||
if (!$handlerIsRegistered) {
|
||||
$handler = $prev[0];
|
||||
} elseif ($handler !== $prev[0] && $replace) {
|
||||
set_exception_handler(array($handler, 'handleException'));
|
||||
$p = $prev[0]->setExceptionHandler(null);
|
||||
$handler->setExceptionHandler($p);
|
||||
$prev[0]->setExceptionHandler($p);
|
||||
}
|
||||
} else {
|
||||
$handler->setExceptionHandler($prev);
|
||||
}
|
||||
|
||||
$handler->throwAt($levels & $handler->thrownErrors, true);
|
||||
@@ -388,13 +403,15 @@ class ErrorHandler
|
||||
*/
|
||||
public function handleError($type, $message, $file, $line)
|
||||
{
|
||||
$level = error_reporting() | E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED;
|
||||
$level = error_reporting();
|
||||
$silenced = 0 === ($level & $type);
|
||||
$level |= E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED;
|
||||
$log = $this->loggedErrors & $type;
|
||||
$throw = $this->thrownErrors & $type & $level;
|
||||
$type &= $level | $this->screamedErrors;
|
||||
|
||||
if (!$type || (!$log && !$throw)) {
|
||||
return $type && $log;
|
||||
return !$silenced && $type && $log;
|
||||
}
|
||||
$scope = $this->scopedErrors & $type;
|
||||
|
||||
@@ -432,7 +449,7 @@ class ErrorHandler
|
||||
$throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line);
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID <= 50407 && (PHP_VERSION_ID >= 50400 || PHP_VERSION_ID <= 50317)) {
|
||||
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.
|
||||
@@ -534,7 +551,7 @@ class ErrorHandler
|
||||
}
|
||||
}
|
||||
|
||||
return $type && $log;
|
||||
return !$silenced && $type && $log;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -547,10 +564,14 @@ class ErrorHandler
|
||||
*/
|
||||
public function handleException($exception, array $error = null)
|
||||
{
|
||||
if (null === $error) {
|
||||
self::$exitCode = 255;
|
||||
}
|
||||
if (!$exception instanceof \Exception) {
|
||||
$exception = new FatalThrowableError($exception);
|
||||
}
|
||||
$type = $exception instanceof FatalErrorException ? $exception->getSeverity() : E_ERROR;
|
||||
$handlerException = null;
|
||||
|
||||
if (($this->loggedErrors & $type) || $exception instanceof FatalThrowableError) {
|
||||
$e = array(
|
||||
@@ -595,18 +616,21 @@ class ErrorHandler
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($this->exceptionHandler)) {
|
||||
throw $exception; // Give back $exception to the native handler
|
||||
}
|
||||
$exceptionHandler = $this->exceptionHandler;
|
||||
$this->exceptionHandler = null;
|
||||
try {
|
||||
call_user_func($this->exceptionHandler, $exception);
|
||||
if (null !== $exceptionHandler) {
|
||||
return \call_user_func($exceptionHandler, $exception);
|
||||
}
|
||||
$handlerException = $handlerException ?: $exception;
|
||||
} catch (\Exception $handlerException) {
|
||||
} catch (\Throwable $handlerException) {
|
||||
}
|
||||
if (isset($handlerException)) {
|
||||
$this->exceptionHandler = null;
|
||||
$this->handleException($handlerException);
|
||||
if ($exception === $handlerException) {
|
||||
self::$reservedMemory = null; // Disable the fatal error handler
|
||||
throw $exception; // Give back $exception to the native handler
|
||||
}
|
||||
$this->handleException($handlerException);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -622,17 +646,41 @@ class ErrorHandler
|
||||
return;
|
||||
}
|
||||
|
||||
self::$reservedMemory = null;
|
||||
$handler = self::$reservedMemory = null;
|
||||
$handlers = array();
|
||||
$previousHandler = null;
|
||||
$sameHandlerLimit = 10;
|
||||
|
||||
$handler = set_error_handler('var_dump');
|
||||
$handler = is_array($handler) ? $handler[0] : null;
|
||||
restore_error_handler();
|
||||
while (!is_array($handler) || !$handler[0] instanceof self) {
|
||||
$handler = set_exception_handler('var_dump');
|
||||
restore_exception_handler();
|
||||
|
||||
if (!$handler instanceof self) {
|
||||
if (!$handler) {
|
||||
break;
|
||||
}
|
||||
restore_exception_handler();
|
||||
|
||||
if ($handler !== $previousHandler) {
|
||||
array_unshift($handlers, $handler);
|
||||
$previousHandler = $handler;
|
||||
} elseif (0 === --$sameHandlerLimit) {
|
||||
$handler = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach ($handlers as $h) {
|
||||
set_exception_handler($h);
|
||||
}
|
||||
if (!$handler) {
|
||||
return;
|
||||
}
|
||||
if ($handler !== $h) {
|
||||
$handler[0]->setExceptionHandler($h);
|
||||
}
|
||||
$handler = $handler[0];
|
||||
$handlers = array();
|
||||
|
||||
if (null === $error) {
|
||||
if ($exit = null === $error) {
|
||||
$error = error_get_last();
|
||||
}
|
||||
|
||||
@@ -656,15 +704,21 @@ class ErrorHandler
|
||||
} else {
|
||||
$exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true, $trace);
|
||||
}
|
||||
} elseif (!isset($exception)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$handler->handleException($exception, $error);
|
||||
if (isset($exception)) {
|
||||
self::$exitCode = 255;
|
||||
$handler->handleException($exception, $error);
|
||||
}
|
||||
} catch (FatalErrorException $e) {
|
||||
// Ignore this re-throw
|
||||
}
|
||||
|
||||
if ($exit && self::$exitCode) {
|
||||
$exitCode = self::$exitCode;
|
||||
register_shutdown_function('register_shutdown_function', function () use ($exitCode) { exit($exitCode); });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -733,7 +787,7 @@ class ErrorHandler
|
||||
*/
|
||||
public function setLevel($level)
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the throwAt() method instead.', E_USER_DEPRECATED);
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the throwAt() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
$level = null === $level ? error_reporting() : $level;
|
||||
$this->throwAt($level, true);
|
||||
@@ -748,7 +802,7 @@ class ErrorHandler
|
||||
*/
|
||||
public function setDisplayErrors($displayErrors)
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the throwAt() method instead.', E_USER_DEPRECATED);
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the throwAt() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
if ($displayErrors) {
|
||||
$this->throwAt($this->displayErrors, true);
|
||||
@@ -769,7 +823,7 @@ class ErrorHandler
|
||||
*/
|
||||
public static function setLogger(LoggerInterface $logger, $channel = 'deprecation')
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' static method is deprecated since version 2.6 and will be removed in 3.0. Use the setLoggers() or setDefaultLogger() methods instead.', E_USER_DEPRECATED);
|
||||
@trigger_error('The '.__METHOD__.' static method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the setLoggers() or setDefaultLogger() methods instead.', E_USER_DEPRECATED);
|
||||
|
||||
$handler = set_error_handler('var_dump');
|
||||
$handler = is_array($handler) ? $handler[0] : null;
|
||||
@@ -794,7 +848,7 @@ class ErrorHandler
|
||||
*/
|
||||
public function handle($level, $message, $file = 'unknown', $line = 0, $context = array())
|
||||
{
|
||||
$this->handleError(E_USER_DEPRECATED, 'The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the handleError() method instead.', __FILE__, __LINE__, array());
|
||||
$this->handleError(E_USER_DEPRECATED, 'The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the handleError() method instead.', __FILE__, __LINE__, array());
|
||||
|
||||
return $this->handleError($level, $message, $file, $line, (array) $context);
|
||||
}
|
||||
@@ -806,7 +860,7 @@ class ErrorHandler
|
||||
*/
|
||||
public function handleFatal()
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the handleFatalError() method instead.', E_USER_DEPRECATED);
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the handleFatalError() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
static::handleFatalError();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@ class ClassNotFoundException extends FatalErrorException
|
||||
$previous->getSeverity(),
|
||||
$previous->getFile(),
|
||||
$previous->getLine(),
|
||||
null,
|
||||
true,
|
||||
null,
|
||||
$previous->getPrevious()
|
||||
);
|
||||
$this->setTrace($previous->getTrace());
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\Debug\Exception;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\DummyException class is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
@trigger_error('The '.__NAMESPACE__.'\DummyException class is deprecated since Symfony 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
|
||||
@@ -35,9 +35,9 @@ use Symfony\Component\HttpKernel\Exception\FatalErrorException as LegacyFatalErr
|
||||
*/
|
||||
class FatalErrorException extends LegacyFatalErrorException
|
||||
{
|
||||
public function __construct($message, $code, $severity, $filename, $lineno, $traceOffset = null, $traceArgs = true, array $trace = null)
|
||||
public function __construct($message, $code, $severity, $filename, $lineno, $traceOffset = null, $traceArgs = true, array $trace = null, $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $severity, $filename, $lineno);
|
||||
parent::__construct($message, $code, $severity, $filename, $lineno, $previous);
|
||||
|
||||
if (null !== $trace) {
|
||||
if (!$traceArgs) {
|
||||
|
||||
@@ -36,7 +36,8 @@ class FatalThrowableError extends FatalErrorException
|
||||
$e->getCode(),
|
||||
$severity,
|
||||
$e->getFile(),
|
||||
$e->getLine()
|
||||
$e->getLine(),
|
||||
$e->getPrevious()
|
||||
);
|
||||
|
||||
$this->setTrace($e->getTrace());
|
||||
|
||||
@@ -26,6 +26,9 @@ class UndefinedFunctionException extends FatalErrorException
|
||||
$previous->getSeverity(),
|
||||
$previous->getFile(),
|
||||
$previous->getLine(),
|
||||
null,
|
||||
true,
|
||||
null,
|
||||
$previous->getPrevious()
|
||||
);
|
||||
$this->setTrace($previous->getTrace());
|
||||
|
||||
@@ -26,6 +26,9 @@ class UndefinedMethodException extends FatalErrorException
|
||||
$previous->getSeverity(),
|
||||
$previous->getFile(),
|
||||
$previous->getLine(),
|
||||
null,
|
||||
true,
|
||||
null,
|
||||
$previous->getPrevious()
|
||||
);
|
||||
$this->setTrace($previous->getTrace());
|
||||
|
||||
@@ -39,7 +39,7 @@ class ExceptionHandler
|
||||
public function __construct($debug = true, $charset = null, $fileLinkFormat = null)
|
||||
{
|
||||
if (false !== strpos($charset, '%')) {
|
||||
@trigger_error('Providing $fileLinkFormat as second argument to '.__METHOD__.' is deprecated since version 2.8 and will be unsupported in 3.0. Please provide it as third argument, after $charset.', E_USER_DEPRECATED);
|
||||
@trigger_error('Providing $fileLinkFormat as second argument to '.__METHOD__.' is deprecated since Symfony 2.8 and will be unsupported in 3.0. Please provide it as third argument, after $charset.', E_USER_DEPRECATED);
|
||||
|
||||
// Swap $charset and $fileLinkFormat for BC reasons
|
||||
$pivot = $fileLinkFormat;
|
||||
@@ -153,8 +153,6 @@ class ExceptionHandler
|
||||
* If you have the Symfony HttpFoundation component installed,
|
||||
* this method will use it to create and send the response. If not,
|
||||
* it will fallback to plain PHP functions.
|
||||
*
|
||||
* @param \Exception $exception An \Exception instance
|
||||
*/
|
||||
private function failSafeHandle(\Exception $exception)
|
||||
{
|
||||
@@ -166,7 +164,7 @@ class ExceptionHandler
|
||||
$response = $this->createResponse($exception);
|
||||
$response->sendHeaders();
|
||||
$response->sendContent();
|
||||
@trigger_error(sprintf("The %s::createResponse method is deprecated since 2.8 and won't be called anymore when handling an exception in 3.0.", $reflector->class), E_USER_DEPRECATED);
|
||||
@trigger_error(sprintf("The %s::createResponse method is deprecated since Symfony 2.8 and won't be called anymore when handling an exception in 3.0.", $reflector->class), E_USER_DEPRECATED);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -210,7 +208,7 @@ class ExceptionHandler
|
||||
*/
|
||||
public function createResponse($exception)
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
|
||||
if (!$exception instanceof FlattenException) {
|
||||
$exception = FlattenException::create($exception);
|
||||
@@ -238,8 +236,6 @@ class ExceptionHandler
|
||||
/**
|
||||
* Gets the HTML content associated with the given exception.
|
||||
*
|
||||
* @param FlattenException $exception A FlattenException instance
|
||||
*
|
||||
* @return string The content as a string
|
||||
*/
|
||||
public function getContent(FlattenException $exception)
|
||||
@@ -306,8 +302,6 @@ EOF;
|
||||
/**
|
||||
* Gets the stylesheet associated with the given exception.
|
||||
*
|
||||
* @param FlattenException $exception A FlattenException instance
|
||||
*
|
||||
* @return string The stylesheet as a string
|
||||
*/
|
||||
public function getStylesheet(FlattenException $exception)
|
||||
@@ -442,7 +436,7 @@ EOF;
|
||||
$formattedValue = str_replace("\n", '', var_export($this->escapeHtml((string) $item[1]), true));
|
||||
}
|
||||
|
||||
$result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue);
|
||||
$result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $this->escapeHtml($key), $formattedValue);
|
||||
}
|
||||
|
||||
return implode(', ', $result);
|
||||
@@ -455,9 +449,9 @@ EOF;
|
||||
*/
|
||||
protected static function utf8Htmlize($str)
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
|
||||
return htmlspecialchars($str, ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), 'UTF-8');
|
||||
return htmlspecialchars($str, ENT_QUOTES | (\PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -465,7 +459,7 @@ EOF;
|
||||
*/
|
||||
private function escapeHtml($str)
|
||||
{
|
||||
return htmlspecialchars($str, ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), $this->charset);
|
||||
return htmlspecialchars($str, ENT_QUOTES | (\PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), $this->charset);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2004-2017 Fabien Potencier
|
||||
Copyright (c) 2004-2018 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
--TEST--
|
||||
Test symfony_zval_info API
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('symfony_debug')) print 'skip'; ?>
|
||||
<?php if (!extension_loaded('symfony_debug')) {
|
||||
echo 'skip';
|
||||
} ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
--TEST--
|
||||
Test symfony_debug_backtrace in case of fatal error
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('symfony_debug')) print 'skip'; ?>
|
||||
<?php if (!extension_loaded('symfony_debug')) {
|
||||
echo 'skip';
|
||||
} ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
--TEST--
|
||||
Test symfony_debug_backtrace in case of non fatal error
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('symfony_debug')) print 'skip'; ?>
|
||||
<?php if (!extension_loaded('symfony_debug')) {
|
||||
echo 'skip';
|
||||
} ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
--TEST--
|
||||
Test ErrorHandler in case of fatal error
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('symfony_debug')) print 'skip'; ?>
|
||||
<?php if (!extension_loaded('symfony_debug')) {
|
||||
echo 'skip';
|
||||
} ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -59,9 +59,26 @@ class DebugClassLoaderTest extends TestCase
|
||||
$this->fail('DebugClassLoader did not register');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Exception
|
||||
* @expectedExceptionMessage boo
|
||||
*/
|
||||
public function testThrowingClass()
|
||||
{
|
||||
try {
|
||||
class_exists(__NAMESPACE__.'\Fixtures\Throwing');
|
||||
$this->fail('Exception expected');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertSame('boo', $e->getMessage());
|
||||
}
|
||||
|
||||
// the second call also should throw
|
||||
class_exists(__NAMESPACE__.'\Fixtures\Throwing');
|
||||
}
|
||||
|
||||
public function testUnsilencing()
|
||||
{
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
$this->markTestSkipped('PHP7 throws exceptions, unsilencing is not required anymore.');
|
||||
}
|
||||
if (defined('HHVM_VERSION')) {
|
||||
@@ -111,7 +128,7 @@ class DebugClassLoaderTest extends TestCase
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
$this->assertStringStartsWith(__FILE__, $exception->getFile());
|
||||
if (PHP_VERSION_ID < 70000) {
|
||||
if (\PHP_VERSION_ID < 70000) {
|
||||
$this->assertRegExp('/^Runtime Notice: Declaration/', $exception->getMessage());
|
||||
$this->assertEquals(E_STRICT, $exception->getSeverity());
|
||||
} else {
|
||||
@@ -128,6 +145,7 @@ class DebugClassLoaderTest extends TestCase
|
||||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
* @expectedExceptionMessage Case mismatch between loaded and declared class names
|
||||
*/
|
||||
public function testNameCaseMismatch()
|
||||
{
|
||||
@@ -149,6 +167,7 @@ class DebugClassLoaderTest extends TestCase
|
||||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
* @expectedExceptionMessage Case mismatch between loaded and declared class names
|
||||
*/
|
||||
public function testPsr4CaseMismatch()
|
||||
{
|
||||
@@ -189,7 +208,7 @@ class DebugClassLoaderTest extends TestCase
|
||||
|
||||
$xError = array(
|
||||
'type' => E_USER_DEPRECATED,
|
||||
'message' => 'The Test\Symfony\Component\Debug\Tests\\'.$class.' class '.$type.' Symfony\Component\Debug\Tests\Fixtures\\'.$super.' that is deprecated but this is a test deprecation notice.',
|
||||
'message' => 'The Test\Symfony\Component\Debug\Tests\\'.$class.' class '.$type.' Symfony\Component\Debug\Tests\Fixtures\\'.$super.' that is deprecated but this is a test deprecation notice',
|
||||
);
|
||||
|
||||
$this->assertSame($xError, $lastError);
|
||||
@@ -249,7 +268,7 @@ class DebugClassLoaderTest extends TestCase
|
||||
|
||||
public function testReservedForPhp7()
|
||||
{
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
$this->markTestSkipped('PHP7 already prevents using reserved names.');
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ class ErrorHandlerTest extends TestCase
|
||||
|
||||
$newHandler = new ErrorHandler();
|
||||
|
||||
$this->assertSame($newHandler, ErrorHandler::register($newHandler, false));
|
||||
$this->assertSame($handler, ErrorHandler::register($newHandler, false));
|
||||
$h = set_error_handler('var_dump');
|
||||
restore_error_handler();
|
||||
$this->assertSame(array($handler, 'handleError'), $h);
|
||||
@@ -65,6 +65,30 @@ class ErrorHandlerTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function testErrorGetLast()
|
||||
{
|
||||
$handler = ErrorHandler::register();
|
||||
$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
|
||||
$handler->setDefaultLogger($logger);
|
||||
$handler->screamAt(E_ALL);
|
||||
|
||||
try {
|
||||
@trigger_error('Hello', E_USER_WARNING);
|
||||
$expected = array(
|
||||
'type' => E_USER_WARNING,
|
||||
'message' => 'Hello',
|
||||
'file' => __FILE__,
|
||||
'line' => __LINE__ - 5,
|
||||
);
|
||||
$this->assertSame($expected, error_get_last());
|
||||
} catch (\Exception $e) {
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function testNotice()
|
||||
{
|
||||
ErrorHandler::register();
|
||||
@@ -80,7 +104,9 @@ class ErrorHandlerTest extends TestCase
|
||||
$this->assertEquals(E_NOTICE, $exception->getSeverity());
|
||||
$this->assertEquals(__FILE__, $exception->getFile());
|
||||
$this->assertRegExp('/^Notice: Undefined variable: (foo|bar)/', $exception->getMessage());
|
||||
$this->assertArrayHasKey('foobar', $exception->getContext());
|
||||
if (\PHP_VERSION_ID < 70200) {
|
||||
$this->assertArrayHasKey('foobar', $exception->getContext());
|
||||
}
|
||||
|
||||
$trace = $exception->getTrace();
|
||||
$this->assertEquals(__FILE__, $trace[0]['file']);
|
||||
@@ -319,6 +345,9 @@ class ErrorHandlerTest extends TestCase
|
||||
@$handler->handleError(E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group no-hhvm
|
||||
*/
|
||||
public function testHandleException()
|
||||
{
|
||||
try {
|
||||
@@ -444,6 +473,9 @@ class ErrorHandlerTest extends TestCase
|
||||
$handler->setLoggers(array(E_DEPRECATED => array($mockLogger, LogLevel::WARNING)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group no-hhvm
|
||||
*/
|
||||
public function testHandleFatalError()
|
||||
{
|
||||
try {
|
||||
@@ -503,6 +535,9 @@ class ErrorHandlerTest extends TestCase
|
||||
$this->assertStringStartsWith("Attempted to load class \"Foo\" from the global namespace.\nDid you forget a \"use\" statement", $args[0]->getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group no-hhvm
|
||||
*/
|
||||
public function testHandleFatalErrorOnHHVM()
|
||||
{
|
||||
try {
|
||||
@@ -590,4 +625,18 @@ class ErrorHandlerTest extends TestCase
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Exception
|
||||
* @group no-hhvm
|
||||
*/
|
||||
public function testCustomExceptionHandler()
|
||||
{
|
||||
$handler = new ErrorHandler();
|
||||
$handler->setExceptionHandler(function ($e) use ($handler) {
|
||||
$handler->handleException($e);
|
||||
});
|
||||
|
||||
$handler->handleException(new \Exception());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ class FlattenExceptionTest extends TestCase
|
||||
/**
|
||||
* @dataProvider flattenDataProvider
|
||||
*/
|
||||
public function testFlattenHttpException(\Exception $exception, $statusCode)
|
||||
public function testFlattenHttpException(\Exception $exception)
|
||||
{
|
||||
$flattened = FlattenException::create($exception);
|
||||
$flattened2 = FlattenException::create($exception);
|
||||
@@ -120,7 +120,7 @@ class FlattenExceptionTest extends TestCase
|
||||
/**
|
||||
* @dataProvider flattenDataProvider
|
||||
*/
|
||||
public function testPrevious(\Exception $exception, $statusCode)
|
||||
public function testPrevious(\Exception $exception)
|
||||
{
|
||||
$flattened = FlattenException::create($exception);
|
||||
$flattened2 = FlattenException::create($exception);
|
||||
@@ -167,7 +167,7 @@ class FlattenExceptionTest extends TestCase
|
||||
/**
|
||||
* @dataProvider flattenDataProvider
|
||||
*/
|
||||
public function testToArray(\Exception $exception, $statusCode)
|
||||
public function testToArray(\Exception $exception)
|
||||
{
|
||||
$flattened = FlattenException::create($exception);
|
||||
$flattened->setTrace(array(), 'foo.php', 123);
|
||||
@@ -187,12 +187,13 @@ class FlattenExceptionTest extends TestCase
|
||||
public function flattenDataProvider()
|
||||
{
|
||||
return array(
|
||||
array(new \Exception('test', 123), 500),
|
||||
array(new \Exception('test', 123)),
|
||||
);
|
||||
}
|
||||
|
||||
public function testRecursionInArguments()
|
||||
{
|
||||
$a = null;
|
||||
$a = array('foo', array(2, &$a));
|
||||
$exception = $this->createException($a);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace Symfony\Component\Debug\Tests\Fixtures;
|
||||
|
||||
/**
|
||||
* @deprecated but this is a test
|
||||
* deprecation notice.
|
||||
* deprecation notice
|
||||
* @foobar
|
||||
*/
|
||||
class DeprecatedClass
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace Symfony\Component\Debug\Tests\Fixtures;
|
||||
|
||||
/**
|
||||
* @deprecated but this is a test
|
||||
* deprecation notice.
|
||||
* deprecation notice
|
||||
* @foobar
|
||||
*/
|
||||
interface DeprecatedInterface
|
||||
|
||||
3
Tests/Fixtures/Throwing.php
Normal file
3
Tests/Fixtures/Throwing.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
throw new \Exception('boo');
|
||||
47
Tests/phpt/decorate_exception_hander.phpt
Normal file
47
Tests/phpt/decorate_exception_hander.phpt
Normal file
@@ -0,0 +1,47 @@
|
||||
--TEST--
|
||||
Test catching fatal errors when handlers are nested
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Debug;
|
||||
|
||||
$vendor = __DIR__;
|
||||
while (!file_exists($vendor.'/vendor')) {
|
||||
$vendor = dirname($vendor);
|
||||
}
|
||||
require $vendor.'/vendor/autoload.php';
|
||||
|
||||
set_error_handler('var_dump');
|
||||
set_exception_handler('var_dump');
|
||||
|
||||
ErrorHandler::register(null, false);
|
||||
|
||||
if (true) {
|
||||
class foo extends missing
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Class 'Symfony\Component\Debug\missing' not found in %s on line %d
|
||||
object(Symfony\Component\Debug\Exception\ClassNotFoundException)#%d (8) {
|
||||
["message":protected]=>
|
||||
string(131) "Attempted to load class "missing" from namespace "Symfony\Component\Debug".
|
||||
Did you forget a "use" statement for another namespace?"
|
||||
["string":"Exception":private]=>
|
||||
string(0) ""
|
||||
["code":protected]=>
|
||||
int(0)
|
||||
["file":protected]=>
|
||||
string(%d) "%s"
|
||||
["line":protected]=>
|
||||
int(%d)
|
||||
["trace":"Exception":private]=>
|
||||
array(0) {
|
||||
}
|
||||
["previous":"Exception":private]=>
|
||||
NULL
|
||||
["severity":protected]=>
|
||||
int(1)
|
||||
}
|
||||
35
Tests/phpt/exception_rethrown.phpt
Normal file
35
Tests/phpt/exception_rethrown.phpt
Normal file
@@ -0,0 +1,35 @@
|
||||
--TEST--
|
||||
Test rethrowing in custom exception handler
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Debug;
|
||||
|
||||
$vendor = __DIR__;
|
||||
while (!file_exists($vendor.'/vendor')) {
|
||||
$vendor = dirname($vendor);
|
||||
}
|
||||
require $vendor.'/vendor/autoload.php';
|
||||
|
||||
if (true) {
|
||||
class TestLogger extends \Psr\Log\AbstractLogger
|
||||
{
|
||||
public function log($level, $message, array $context = array())
|
||||
{
|
||||
echo $message, "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set_exception_handler(function ($e) { echo 123; throw $e; });
|
||||
ErrorHandler::register()->setDefaultLogger(new TestLogger());
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
throw new \Exception('foo');
|
||||
?>
|
||||
--EXPECTF--
|
||||
Uncaught Exception: foo
|
||||
123
|
||||
Fatal error: Uncaught %s:25
|
||||
Stack trace:
|
||||
%a
|
||||
42
Tests/phpt/fatal_with_nested_handlers.phpt
Normal file
42
Tests/phpt/fatal_with_nested_handlers.phpt
Normal file
@@ -0,0 +1,42 @@
|
||||
--TEST--
|
||||
Test catching fatal errors when handlers are nested
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Debug;
|
||||
|
||||
$vendor = __DIR__;
|
||||
while (!file_exists($vendor.'/vendor')) {
|
||||
$vendor = dirname($vendor);
|
||||
}
|
||||
require $vendor.'/vendor/autoload.php';
|
||||
|
||||
Debug::enable();
|
||||
ini_set('display_errors', 0);
|
||||
|
||||
$eHandler = set_error_handler('var_dump');
|
||||
$xHandler = set_exception_handler('var_dump');
|
||||
|
||||
var_dump(array(
|
||||
$eHandler[0] === $xHandler[0] ? 'Error and exception handlers do match' : 'Error and exception handlers are different',
|
||||
));
|
||||
|
||||
$eHandler[0]->setExceptionHandler('print_r');
|
||||
|
||||
if (true) {
|
||||
class Broken implements \Serializable
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(37) "Error and exception handlers do match"
|
||||
}
|
||||
object(Symfony\Component\Debug\Exception\FatalErrorException)#%d (%d) {
|
||||
["message":protected]=>
|
||||
string(199) "Error: Class Symfony\Component\Debug\Broken contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (Serializable::serialize, Serializable::unserialize)"
|
||||
%a
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/class-loader": "~2.2|~3.0.0",
|
||||
"symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0"
|
||||
"symfony/http-kernel": "~2.3.24|~2.5.9|^2.6.2|~3.0.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Component\\Debug\\": "" },
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
backupGlobals="false"
|
||||
colors="true"
|
||||
bootstrap="vendor/autoload.php"
|
||||
failOnRisky="true"
|
||||
failOnWarning="true"
|
||||
>
|
||||
<php>
|
||||
<ini name="error_reporting" value="-1" />
|
||||
|
||||
Reference in New Issue
Block a user