[Debug] fix and enhance exception messages
This commit is contained in:
parent
1d7684ac3d
commit
8df1ce826f
@ -210,9 +210,11 @@ class ExceptionHandler
|
||||
$class = $this->formatClass($e['class']);
|
||||
$message = nl2br(self::utf8Htmlize($e['message']));
|
||||
$content .= sprintf(<<<EOF
|
||||
<div class="block_exception clear_fix">
|
||||
<h2><span>%d/%d</span> %s%s:<br />%s</h2>
|
||||
</div>
|
||||
<h2 class="block_exception clear_fix">
|
||||
<span class="exception_counter">%d/%d</span>
|
||||
<span class="exception_title">%s%s:</span>
|
||||
<span class="exception_message">%s</span>
|
||||
</h2>
|
||||
<div class="block">
|
||||
<ol class="traces list_exception">
|
||||
|
||||
@ -269,12 +271,14 @@ EOF;
|
||||
.sf-reset abbr { border-bottom: 1px dotted #000; cursor: help; }
|
||||
.sf-reset p { font-size:14px; line-height:20px; color:#868686; padding-bottom:20px }
|
||||
.sf-reset strong { font-weight:bold; }
|
||||
.sf-reset a { color:#6c6159; }
|
||||
.sf-reset a { color:#6c6159; cursor: default; }
|
||||
.sf-reset a img { border:none; }
|
||||
.sf-reset a:hover { text-decoration:underline; }
|
||||
.sf-reset em { font-style:italic; }
|
||||
.sf-reset h1, .sf-reset h2 { font: 20px Georgia, "Times New Roman", Times, serif }
|
||||
.sf-reset h2 span { background-color: #fff; color: #333; padding: 6px; float: left; margin-right: 10px; }
|
||||
.sf-reset .exception_counter { background-color: #fff; color: #333; padding: 6px; float: left; margin-right: 10px; float: left; display: block; }
|
||||
.sf-reset .exception_title { margin-left: 3em; margin-bottom: 0.7em; display: block; }
|
||||
.sf-reset .exception_message { margin-left: 3em; display: block; }
|
||||
.sf-reset .traces li { font-size:12px; padding: 2px 4px; list-style-type:decimal; margin-left:20px; }
|
||||
.sf-reset .block { background-color:#FFFFFF; padding:10px 28px; margin-bottom:20px;
|
||||
-webkit-border-bottom-right-radius: 16px;
|
||||
@ -352,10 +356,10 @@ EOF;
|
||||
if ($linkFormat = ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format')) {
|
||||
$link = str_replace(array('%f', '%l'), array($path, $line), $linkFormat);
|
||||
|
||||
return sprintf(' <a href="%s" title="Go to source">in %s line %d</a>', $link, $file, $line);
|
||||
return sprintf(' in <a href="%s" title="Go to source">%s line %d</a>', $link, $file, $line);
|
||||
}
|
||||
|
||||
return sprintf(' <a title="in %s line %3$d" ondblclick="var f=this.innerHTML;this.innerHTML=this.title;this.title=f;">in %s line %d</a>', $path, $file, $line);
|
||||
return sprintf(' in <a title="%s line %3$d" ondblclick="var f=this.innerHTML;this.innerHTML=this.title;this.title=f;">%s line %d</a>', $path, $file, $line);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -67,7 +67,7 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
|
||||
$tail = ' for "'.$tail;
|
||||
}
|
||||
}
|
||||
$message .= ' Did you forget a "use" statement'.$tail;
|
||||
$message .= "\nDid you forget a \"use\" statement".$tail;
|
||||
|
||||
return new ClassNotFoundException($message, $exception);
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ class UndefinedFunctionFatalErrorHandler implements FatalErrorHandlerInterface
|
||||
} else {
|
||||
$candidates = '"'.$last;
|
||||
}
|
||||
$message .= ' Did you mean to call '.$candidates;
|
||||
$message .= "\nDid you mean to call ".$candidates;
|
||||
}
|
||||
|
||||
return new UndefinedFunctionException($message, $exception);
|
||||
|
@ -52,7 +52,7 @@ class UndefinedMethodFatalErrorHandler implements FatalErrorHandlerInterface
|
||||
} else {
|
||||
$candidates = '"'.$last;
|
||||
}
|
||||
$message .= ' Did you mean to call '.$candidates;
|
||||
$message .= "\nDid you mean to call ".$candidates;
|
||||
}
|
||||
|
||||
return new UndefinedMethodException($message, $exception);
|
||||
|
@ -25,13 +25,13 @@ class ExceptionHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
$response = $handler->createResponse(new \RuntimeException('Foo'));
|
||||
|
||||
$this->assertContains('<h1>Whoops, looks like something went wrong.</h1>', $response->getContent());
|
||||
$this->assertNotContains('<div class="block_exception clear_fix">', $response->getContent());
|
||||
$this->assertNotContains('<h2 class="block_exception clear_fix">', $response->getContent());
|
||||
|
||||
$handler = new ExceptionHandler(true);
|
||||
$response = $handler->createResponse(new \RuntimeException('Foo'));
|
||||
|
||||
$this->assertContains('<h1>Whoops, looks like something went wrong.</h1>', $response->getContent());
|
||||
$this->assertContains('<div class="block_exception clear_fix">', $response->getContent());
|
||||
$this->assertContains('<h2 class="block_exception clear_fix">', $response->getContent());
|
||||
}
|
||||
|
||||
public function testStatusCode()
|
||||
|
@ -41,7 +41,7 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
'file' => 'foo.php',
|
||||
'message' => 'Class \'WhizBangFactory\' not found',
|
||||
),
|
||||
'Attempted to load class "WhizBangFactory" from the global namespace. Did you forget a "use" statement?',
|
||||
"Attempted to load class \"WhizBangFactory\" from the global namespace.\nDid you forget a \"use\" statement?",
|
||||
),
|
||||
array(
|
||||
array(
|
||||
@ -50,7 +50,7 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
'file' => 'foo.php',
|
||||
'message' => 'Class \'Foo\\Bar\\WhizBangFactory\' not found',
|
||||
),
|
||||
'Attempted to load class "WhizBangFactory" from namespace "Foo\\Bar". Did you forget a "use" statement for another namespace?',
|
||||
"Attempted to load class \"WhizBangFactory\" from namespace \"Foo\\Bar\".\nDid you forget a \"use\" statement for another namespace?",
|
||||
),
|
||||
array(
|
||||
array(
|
||||
@ -59,7 +59,7 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
'file' => 'foo.php',
|
||||
'message' => 'Class \'UndefinedFunctionException\' not found',
|
||||
),
|
||||
'Attempted to load class "UndefinedFunctionException" from the global namespace. Did you forget a "use" statement for "Symfony\Component\Debug\Exception\UndefinedFunctionException"?',
|
||||
"Attempted to load class \"UndefinedFunctionException\" from the global namespace.\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
|
||||
),
|
||||
array(
|
||||
array(
|
||||
@ -68,7 +68,7 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
'file' => 'foo.php',
|
||||
'message' => 'Class \'PEARClass\' not found',
|
||||
),
|
||||
'Attempted to load class "PEARClass" from the global namespace. Did you forget a "use" statement for "Symfony_Component_Debug_Tests_Fixtures_PEARClass"?',
|
||||
"Attempted to load class \"PEARClass\" from the global namespace.\nDid you forget a \"use\" statement for \"Symfony_Component_Debug_Tests_Fixtures_PEARClass\"?",
|
||||
),
|
||||
array(
|
||||
array(
|
||||
@ -77,7 +77,7 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
'file' => 'foo.php',
|
||||
'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
|
||||
),
|
||||
'Attempted to load class "UndefinedFunctionException" from namespace "Foo\Bar". Did you forget a "use" statement for "Symfony\Component\Debug\Exception\UndefinedFunctionException"?',
|
||||
"Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ class UndefinedFunctionFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
'file' => 'foo.php',
|
||||
'message' => 'Call to undefined function test_namespaced_function()',
|
||||
),
|
||||
'Attempted to call function "test_namespaced_function" from the global namespace. Did you mean to call "\\symfony\\component\\debug\\tests\\fatalerrorhandler\\test_namespaced_function"?',
|
||||
"Attempted to call function \"test_namespaced_function\" from the global namespace.\nDid you mean to call \"\\symfony\\component\\debug\\tests\\fatalerrorhandler\\test_namespaced_function\"?",
|
||||
),
|
||||
array(
|
||||
array(
|
||||
@ -51,7 +51,7 @@ class UndefinedFunctionFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
'file' => 'foo.php',
|
||||
'message' => 'Call to undefined function Foo\\Bar\\Baz\\test_namespaced_function()',
|
||||
),
|
||||
'Attempted to call function "test_namespaced_function" from namespace "Foo\\Bar\\Baz". Did you mean to call "\\symfony\\component\\debug\\tests\\fatalerrorhandler\\test_namespaced_function"?',
|
||||
"Attempted to call function \"test_namespaced_function\" from namespace \"Foo\\Bar\\Baz\".\nDid you mean to call \"\\symfony\\component\\debug\\tests\\fatalerrorhandler\\test_namespaced_function\"?",
|
||||
),
|
||||
array(
|
||||
array(
|
||||
|
@ -50,7 +50,7 @@ class UndefinedMethodFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
'file' => 'foo.php',
|
||||
'message' => 'Call to undefined method SplObjectStorage::walid()',
|
||||
),
|
||||
'Attempted to call method "walid" on class "SplObjectStorage". Did you mean to call "valid"?',
|
||||
"Attempted to call method \"walid\" on class \"SplObjectStorage\".\nDid you mean to call \"valid\"?",
|
||||
),
|
||||
array(
|
||||
array(
|
||||
@ -59,7 +59,7 @@ class UndefinedMethodFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
'file' => 'foo.php',
|
||||
'message' => 'Call to undefined method SplObjectStorage::offsetFet()',
|
||||
),
|
||||
'Attempted to call method "offsetFet" on class "SplObjectStorage". Did you mean to call e.g. "offsetGet", "offsetSet" or "offsetUnset"?',
|
||||
"Attempted to call method \"offsetFet\" on class \"SplObjectStorage\".\nDid you mean to call e.g. \"offsetGet\", \"offsetSet\" or \"offsetUnset\"?",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Debug\ErrorHandler;
|
||||
use Symfony\Component\Debug\AbstractExceptionHandler;
|
||||
use Symfony\Component\Debug\ExceptionHandler;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
@ -37,9 +37,7 @@ class DebugHandlersListener implements EventSubscriberInterface
|
||||
*/
|
||||
public function __construct($exceptionHandler, LoggerInterface $logger = null, $levels = null, $debug = true)
|
||||
{
|
||||
if (is_callable($exceptionHandler)) {
|
||||
$this->exceptionHandler = $exceptionHandler;
|
||||
}
|
||||
$this->logger = $logger;
|
||||
$this->levels = $levels;
|
||||
$this->debug = $debug;
|
||||
@ -76,7 +74,7 @@ class DebugHandlersListener implements EventSubscriberInterface
|
||||
$handler->setExceptionHandler($h);
|
||||
$handler = is_array($h) ? $h[0] : null;
|
||||
}
|
||||
if ($handler instanceof AbstractExceptionHandler) {
|
||||
if ($handler instanceof ExceptionHandler) {
|
||||
$handler->setHandler($this->exceptionHandler);
|
||||
}
|
||||
$this->exceptionHandler = null;
|
||||
|
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Tests\EventListener;
|
||||
|
||||
use Psr\Log\LogLevel;
|
||||
use Symfony\Component\Debug\ErrorHandler;
|
||||
use Symfony\Component\Debug\ExceptionHandler;
|
||||
use Symfony\Component\HttpKernel\EventListener\DebugHandlersListener;
|
||||
|
||||
/**
|
||||
* DebugHandlersListenerTest
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class DebugHandlersListenerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testConfigure()
|
||||
{
|
||||
$logger = $this->getMock('Psr\Log\LoggerInterface');
|
||||
$userHandler = function() {};
|
||||
$listener = new DebugHandlersListener($userHandler, $logger);
|
||||
$xHandler = new ExceptionHandler();
|
||||
$eHandler = new ErrorHandler();
|
||||
$eHandler->setExceptionHandler(array($xHandler, 'handle'));
|
||||
|
||||
$exception = null;
|
||||
set_error_handler(array($eHandler, 'handleError'));
|
||||
set_exception_handler(array($eHandler, 'handleException'));
|
||||
try {
|
||||
$listener->configure();
|
||||
} catch (\Exception $exception) {
|
||||
}
|
||||
restore_exception_handler();
|
||||
restore_error_handler();
|
||||
|
||||
if (null !== $exception) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
$this->assertSame($userHandler, $xHandler->setHandler('var_dump'));
|
||||
|
||||
$loggers = $eHandler->setLoggers(array());
|
||||
|
||||
$this->assertArrayHasKey(E_DEPRECATED, $loggers);
|
||||
$this->assertSame(array($logger, LogLevel::INFO), $loggers[E_DEPRECATED]);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user