mirror of
https://github.com/symfony/debug.git
synced 2026-04-23 17:08:10 +02:00
Compare commits
8 Commits
v3.3.0-RC1
...
v3.3.3
| Author | SHA1 | Date | |
|---|---|---|---|
| bcfd02728d | |||
| 4e323c3ebd | |||
| e9c5048284 | |||
| 8d4977c296 | |||
| 8470d77011 | |||
| 2662c21dea | |||
| 46cf671348 | |||
| ef5f19a7a6 |
+40
-14
@@ -100,6 +100,8 @@ class ErrorHandler
|
||||
private static $stackedErrors = array();
|
||||
private static $stackedErrorLevels = array();
|
||||
private static $toStringException = null;
|
||||
private static $silencedErrorCache = array();
|
||||
private static $silencedErrorCount = 0;
|
||||
private static $exitCode = 0;
|
||||
|
||||
/**
|
||||
@@ -407,7 +409,24 @@ class ErrorHandler
|
||||
$errorAsException = self::$toStringException;
|
||||
self::$toStringException = null;
|
||||
} elseif (!$throw && !($type & $level)) {
|
||||
$errorAsException = new SilencedErrorContext($type, $file, $line);
|
||||
if (isset(self::$silencedErrorCache[$message])) {
|
||||
$lightTrace = null;
|
||||
$errorAsException = self::$silencedErrorCache[$message];
|
||||
++$errorAsException->count;
|
||||
} else {
|
||||
$lightTrace = $this->tracedErrors & $type ? $this->cleanTrace(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), $type, $file, $line, false) : array();
|
||||
$errorAsException = new SilencedErrorContext($type, $file, $line, $lightTrace);
|
||||
}
|
||||
|
||||
if (100 < ++self::$silencedErrorCount) {
|
||||
self::$silencedErrorCache = $lightTrace = array();
|
||||
self::$silencedErrorCount = 1;
|
||||
}
|
||||
self::$silencedErrorCache[$message] = $errorAsException;
|
||||
|
||||
if (null === $lightTrace) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if ($scope) {
|
||||
$errorAsException = new ContextErrorException($logMessage, 0, $type, $file, $line, $context);
|
||||
@@ -418,19 +437,7 @@ class ErrorHandler
|
||||
// Clean the trace by removing function arguments and the first frames added by the error handler itself.
|
||||
if ($throw || $this->tracedErrors & $type) {
|
||||
$backtrace = $backtrace ?: $errorAsException->getTrace();
|
||||
$lightTrace = $backtrace;
|
||||
|
||||
for ($i = 0; isset($backtrace[$i]); ++$i) {
|
||||
if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) {
|
||||
$lightTrace = array_slice($lightTrace, 1 + $i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!($throw || $this->scopedErrors & $type)) {
|
||||
for ($i = 0; isset($lightTrace[$i]); ++$i) {
|
||||
unset($lightTrace[$i]['args']);
|
||||
}
|
||||
}
|
||||
$lightTrace = $this->cleanTrace($backtrace, $type, $file, $line, $throw);
|
||||
$this->traceReflector->setValue($errorAsException, $lightTrace);
|
||||
} else {
|
||||
$this->traceReflector->setValue($errorAsException, array());
|
||||
@@ -687,4 +694,23 @@ class ErrorHandler
|
||||
new ClassNotFoundFatalErrorHandler(),
|
||||
);
|
||||
}
|
||||
|
||||
private function cleanTrace($backtrace, $type, $file, $line, $throw)
|
||||
{
|
||||
$lightTrace = $backtrace;
|
||||
|
||||
for ($i = 0; isset($backtrace[$i]); ++$i) {
|
||||
if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) {
|
||||
$lightTrace = array_slice($lightTrace, 1 + $i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!($throw || $this->scopedErrors & $type)) {
|
||||
for ($i = 0; isset($lightTrace[$i]); ++$i) {
|
||||
unset($lightTrace[$i]['args']);
|
||||
}
|
||||
}
|
||||
|
||||
return $lightTrace;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,15 +18,20 @@ namespace Symfony\Component\Debug\Exception;
|
||||
*/
|
||||
class SilencedErrorContext implements \JsonSerializable
|
||||
{
|
||||
public $count = 1;
|
||||
|
||||
private $severity;
|
||||
private $file;
|
||||
private $line;
|
||||
private $trace;
|
||||
|
||||
public function __construct($severity, $file, $line)
|
||||
public function __construct($severity, $file, $line, array $trace = array(), $count = 1)
|
||||
{
|
||||
$this->severity = $severity;
|
||||
$this->file = $file;
|
||||
$this->line = $line;
|
||||
$this->trace = $trace;
|
||||
$this->count = $count;
|
||||
}
|
||||
|
||||
public function getSeverity()
|
||||
@@ -44,12 +49,19 @@ class SilencedErrorContext implements \JsonSerializable
|
||||
return $this->line;
|
||||
}
|
||||
|
||||
public function getTrace()
|
||||
{
|
||||
return $this->trace;
|
||||
}
|
||||
|
||||
public function JsonSerialize()
|
||||
{
|
||||
return array(
|
||||
'severity' => $this->severity,
|
||||
'file' => $this->file,
|
||||
'line' => $this->line,
|
||||
'trace' => $this->trace,
|
||||
'count' => $this->count,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+81
-69
File diff suppressed because one or more lines are too long
@@ -61,7 +61,7 @@ class DebugClassLoaderTest extends TestCase
|
||||
|
||||
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')) {
|
||||
@@ -109,7 +109,7 @@ class DebugClassLoaderTest extends TestCase
|
||||
} catch (\ErrorException $exception) {
|
||||
// if an exception is thrown, the test passed
|
||||
$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 {
|
||||
@@ -245,7 +245,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.');
|
||||
}
|
||||
|
||||
|
||||
@@ -221,12 +221,17 @@ class ErrorHandlerTest extends TestCase
|
||||
|
||||
$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
|
||||
|
||||
$logArgCheck = function ($level, $message, $context) {
|
||||
$line = null;
|
||||
$logArgCheck = function ($level, $message, $context) use (&$line) {
|
||||
$this->assertEquals('Notice: Undefined variable: undefVar', $message);
|
||||
$this->assertArrayHasKey('exception', $context);
|
||||
$exception = $context['exception'];
|
||||
$this->assertInstanceOf(SilencedErrorContext::class, $exception);
|
||||
$this->assertSame(E_NOTICE, $exception->getSeverity());
|
||||
$this->assertSame(__FILE__, $exception->getFile());
|
||||
$this->assertSame($line, $exception->getLine());
|
||||
$this->assertNotEmpty($exception->getTrace());
|
||||
$this->assertSame(1, $exception->count);
|
||||
};
|
||||
|
||||
$logger
|
||||
@@ -239,6 +244,7 @@ class ErrorHandlerTest extends TestCase
|
||||
$handler->setDefaultLogger($logger, E_NOTICE);
|
||||
$handler->screamAt(E_NOTICE);
|
||||
unset($undefVar);
|
||||
$line = __LINE__ + 1;
|
||||
@$undefVar++;
|
||||
|
||||
restore_error_handler();
|
||||
|
||||
@@ -39,8 +39,8 @@ class ExceptionHandlerTest extends TestCase
|
||||
$handler->sendPhpResponse(new \RuntimeException('Foo'));
|
||||
$response = ob_get_clean();
|
||||
|
||||
$this->assertContains('<h1>Whoops, looks like something went wrong.</h1>', $response);
|
||||
$this->assertNotContains('<h2 class="block_exception clear_fix">', $response);
|
||||
$this->assertContains('Whoops, looks like something went wrong.', $response);
|
||||
$this->assertNotContains('<div class="trace trace-as-html">', $response);
|
||||
|
||||
$handler = new ExceptionHandler(true);
|
||||
|
||||
@@ -48,8 +48,8 @@ class ExceptionHandlerTest extends TestCase
|
||||
$handler->sendPhpResponse(new \RuntimeException('Foo'));
|
||||
$response = ob_get_clean();
|
||||
|
||||
$this->assertContains('<h1>Whoops, looks like something went wrong.</h1>', $response);
|
||||
$this->assertContains('<h2 class="block_exception clear_fix">', $response);
|
||||
$this->assertContains('Whoops, looks like something went wrong.', $response);
|
||||
$this->assertContains('<div class="trace trace-as-html">', $response);
|
||||
}
|
||||
|
||||
public function testStatusCode()
|
||||
@@ -94,7 +94,7 @@ class ExceptionHandlerTest extends TestCase
|
||||
$handler->sendPhpResponse(new \RuntimeException('Foo', 0, new \RuntimeException('Bar')));
|
||||
$response = ob_get_clean();
|
||||
|
||||
$this->assertStringMatchesFormat('%A<span class="exception_message">Foo</span>%A<span class="exception_message">Bar</span>%A', $response);
|
||||
$this->assertStringMatchesFormat('%A<p class="break-long-words trace-message">Foo</p>%A<p class="break-long-words trace-message">Bar</p>%A', $response);
|
||||
}
|
||||
|
||||
public function testHandle()
|
||||
|
||||
Reference in New Issue
Block a user