mirror of
https://github.com/symfony/debug.git
synced 2026-03-25 01:32:09 +01:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e3ca9cbde | ||
|
|
47e6788c5b | ||
|
|
a26ddce7fe | ||
|
|
a7e8068943 | ||
|
|
5d48e9c0f8 | ||
|
|
b28fd73fef | ||
|
|
c7d48cc12e | ||
|
|
63299f103f | ||
|
|
fe8838e11c | ||
|
|
fc4afe37fd | ||
|
|
1b95888cfd |
@@ -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)
|
||||
|
||||
@@ -383,14 +383,16 @@ class ErrorHandler
|
||||
public function handleError($type, $message, $file, $line)
|
||||
{
|
||||
// Level is the current error reporting level to manage silent error.
|
||||
$level = error_reporting();
|
||||
$silenced = 0 === ($level & $type);
|
||||
// Strong errors are not authorized to be silenced.
|
||||
$level = error_reporting() | E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED;
|
||||
$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;
|
||||
|
||||
@@ -524,7 +526,7 @@ class ErrorHandler
|
||||
}
|
||||
}
|
||||
|
||||
return $type && $log;
|
||||
return !$silenced && $type && $log;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,9 @@ class ClassNotFoundException extends FatalErrorException
|
||||
$previous->getSeverity(),
|
||||
$previous->getFile(),
|
||||
$previous->getLine(),
|
||||
null,
|
||||
true,
|
||||
null,
|
||||
$previous->getPrevious()
|
||||
);
|
||||
$this->setTrace($previous->getTrace());
|
||||
|
||||
@@ -18,9 +18,9 @@ namespace Symfony\Component\Debug\Exception;
|
||||
*/
|
||||
class FatalErrorException extends \ErrorException
|
||||
{
|
||||
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) {
|
||||
|
||||
@@ -157,7 +157,7 @@ class FlattenException
|
||||
return $this->previous;
|
||||
}
|
||||
|
||||
public function setPrevious(FlattenException $previous)
|
||||
public function setPrevious(self $previous)
|
||||
{
|
||||
$this->previous = $previous;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -40,7 +40,7 @@ class ExceptionHandler
|
||||
{
|
||||
$this->debug = $debug;
|
||||
$this->charset = $charset ?: ini_get('default_charset') ?: 'UTF-8';
|
||||
$this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
|
||||
$this->fileLinkFormat = $fileLinkFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,48 +208,54 @@ class ExceptionHandler
|
||||
$title = 'Whoops, looks like something went wrong.';
|
||||
}
|
||||
|
||||
$content = '';
|
||||
if ($this->debug) {
|
||||
try {
|
||||
$count = count($exception->getAllPrevious());
|
||||
$total = $count + 1;
|
||||
foreach ($exception->toArray() as $position => $e) {
|
||||
$ind = $count - $position + 1;
|
||||
$class = $this->formatClass($e['class']);
|
||||
$message = nl2br($this->escapeHtml($e['message']));
|
||||
$content .= sprintf(<<<'EOF'
|
||||
<div class="trace trace-as-html">
|
||||
<table class="trace-details">
|
||||
<thead class="trace-head"><tr><th>
|
||||
<h3 class="trace-class">
|
||||
<span class="text-muted">(%d/%d)</span>
|
||||
<span class="exception_title">%s</span>
|
||||
</h3>
|
||||
<p class="break-long-words trace-message">%s</p>
|
||||
</th></tr></thead>
|
||||
<tbody>
|
||||
EOF
|
||||
, $ind, $total, $class, $message);
|
||||
foreach ($e['trace'] as $trace) {
|
||||
$content .= '<tr><td>';
|
||||
if ($trace['function']) {
|
||||
$content .= sprintf('at <span class="trace-class">%s</span><span class="trace-type">%s</span><span class="trace-method">%s</span>(<span class="trace-arguments">%s</span>)', $this->formatClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args']));
|
||||
}
|
||||
if (isset($trace['file']) && isset($trace['line'])) {
|
||||
$content .= $this->formatPath($trace['file'], $trace['line']);
|
||||
}
|
||||
$content .= "</td></tr>\n";
|
||||
}
|
||||
if (!$this->debug) {
|
||||
return <<<EOF
|
||||
<div class="container">
|
||||
<h1>$title</h1>
|
||||
</div>
|
||||
EOF;
|
||||
}
|
||||
|
||||
$content .= "</tbody>\n</table>\n</div>\n";
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// something nasty happened and we cannot throw an exception anymore
|
||||
if ($this->debug) {
|
||||
$title = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $this->escapeHtml($e->getMessage()));
|
||||
} else {
|
||||
$title = 'Whoops, looks like something went wrong.';
|
||||
$content = '';
|
||||
try {
|
||||
$count = count($exception->getAllPrevious());
|
||||
$total = $count + 1;
|
||||
foreach ($exception->toArray() as $position => $e) {
|
||||
$ind = $count - $position + 1;
|
||||
$class = $this->formatClass($e['class']);
|
||||
$message = nl2br($this->escapeHtml($e['message']));
|
||||
$content .= sprintf(<<<'EOF'
|
||||
<div class="trace trace-as-html">
|
||||
<table class="trace-details">
|
||||
<thead class="trace-head"><tr><th>
|
||||
<h3 class="trace-class">
|
||||
<span class="text-muted">(%d/%d)</span>
|
||||
<span class="exception_title">%s</span>
|
||||
</h3>
|
||||
<p class="break-long-words trace-message">%s</p>
|
||||
</th></tr></thead>
|
||||
<tbody>
|
||||
EOF
|
||||
, $ind, $total, $class, $message);
|
||||
foreach ($e['trace'] as $trace) {
|
||||
$content .= '<tr><td>';
|
||||
if ($trace['function']) {
|
||||
$content .= sprintf('at <span class="trace-class">%s</span><span class="trace-type">%s</span><span class="trace-method">%s</span>(<span class="trace-arguments">%s</span>)', $this->formatClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args']));
|
||||
}
|
||||
if (isset($trace['file']) && isset($trace['line'])) {
|
||||
$content .= $this->formatPath($trace['file'], $trace['line']);
|
||||
}
|
||||
$content .= "</td></tr>\n";
|
||||
}
|
||||
|
||||
$content .= "</tbody>\n</table>\n</div>\n";
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// something nasty happened and we cannot throw an exception anymore
|
||||
if ($this->debug) {
|
||||
$title = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $this->escapeHtml($e->getMessage()));
|
||||
} else {
|
||||
$title = 'Whoops, looks like something went wrong.';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,6 +284,14 @@ EOF;
|
||||
*/
|
||||
public function getStylesheet(FlattenException $exception)
|
||||
{
|
||||
if (!$this->debug) {
|
||||
return <<<'EOF'
|
||||
body { background-color: #fff; color: #222; font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; margin: 0; }
|
||||
.container { margin: 30px; max-width: 600px; }
|
||||
h1 { color: #dc3545; font-size: 24px; }
|
||||
EOF;
|
||||
}
|
||||
|
||||
return <<<'EOF'
|
||||
body { background-color: #F9F9F9; color: #222; font: 14px/1.4 Helvetica, Arial, sans-serif; margin: 0; padding-bottom: 45px; }
|
||||
|
||||
@@ -355,13 +369,29 @@ EOF;
|
||||
private function formatPath($path, $line)
|
||||
{
|
||||
$file = $this->escapeHtml(preg_match('#[^/\\\\]*+$#', $path, $file) ? $file[0] : $path);
|
||||
$fmt = $this->fileLinkFormat;
|
||||
$fmt = $this->fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
|
||||
|
||||
if ($fmt && $link = is_string($fmt) ? strtr($fmt, array('%f' => $path, '%l' => $line)) : $fmt->format($path, $line)) {
|
||||
return sprintf('<span class="block trace-file-path">in <a href="%s" title="Go to source">%s (line %d)</a></span>', $this->escapeHtml($link), $file, $line);
|
||||
if (!$fmt) {
|
||||
return sprintf('<span class="block trace-file-path">in <a title="%s%3$s"><strong>%s</strong>%s</a></span>', $this->escapeHtml($path), $file, 0 < $line ? ' line '.$line : '');
|
||||
}
|
||||
|
||||
return sprintf('<span class="block trace-file-path">in <a title="%s line %3$d"><strong>%s</strong> (line %d)</a></span>', $this->escapeHtml($path), $file, $line);
|
||||
if (\is_string($fmt)) {
|
||||
$i = strpos($f = $fmt, '&', max(strrpos($f, '%f'), strrpos($f, '%l'))) ?: strlen($f);
|
||||
$fmt = array(substr($f, 0, $i)) + preg_split('/&([^>]++)>/', substr($f, $i), -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
for ($i = 1; isset($fmt[$i]); ++$i) {
|
||||
if (0 === strpos($path, $k = $fmt[$i++])) {
|
||||
$path = substr_replace($path, $fmt[$i], 0, strlen($k));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$link = strtr($fmt[0], array('%f' => $path, '%l' => $line));
|
||||
} else {
|
||||
$link = $fmt->format($path, $line);
|
||||
}
|
||||
|
||||
return sprintf('<span class="block trace-file-path">in <a href="%s" title="Go to source"><strong>%s</string>%s</a></span>', $this->escapeHtml($link), $file, 0 < $line ? ' line '.$line : '');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user