diff --git a/src/Symfony/Component/HttpKernel/Debug/ErrorHandler.php b/src/Symfony/Component/HttpKernel/Debug/ErrorHandler.php
index 605c08626c..197ec03cf3 100644
--- a/src/Symfony/Component/HttpKernel/Debug/ErrorHandler.php
+++ b/src/Symfony/Component/HttpKernel/Debug/ErrorHandler.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\HttpKernel\Debug;
+use Symfony\Component\HttpKernel\Exception\FatalErrorException;
+
/**
* ErrorHandler.
*
@@ -28,10 +30,16 @@ class ErrorHandler
E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
E_DEPRECATED => 'Deprecated',
E_USER_DEPRECATED => 'User Deprecated',
+ E_ERROR => 'Error',
+ E_CORE_ERROR => 'Core Error',
+ E_COMPILE_ERROR => 'Compile Error',
+ E_PARSE => 'Parse',
);
private $level;
+ private $reservedMemory;
+
/**
* Register the error handler.
*
@@ -45,6 +53,8 @@ class ErrorHandler
$handler->setLevel($level);
set_error_handler(array($handler, 'handle'));
+ register_shutdown_function(array($handler, 'handleFatal'));
+ $handler->reservedMemory = str_repeat('x', 10240);
return $handler;
}
@@ -69,4 +79,28 @@ class ErrorHandler
return false;
}
+
+ public function handleFatal()
+ {
+ if (null === $error = error_get_last()) {
+ return;
+ }
+
+ unset($this->reservedMemory);
+ $type = $error['type'];
+ if (0 === $this->level || !in_array($type, array(E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE))) {
+ return;
+ }
+
+ // get current exception handler
+ $exceptionHandler = set_exception_handler(function() {});
+ restore_exception_handler();
+
+ if (is_array($exceptionHandler) && $exceptionHandler[0] instanceof ExceptionHandler) {
+ $level = isset($this->levels[$type]) ? $this->levels[$type] : $type;
+ $message = sprintf('%s: %s in %s line %d', $level, $error['message'], $error['file'], $error['line']);
+ $exception = new FatalErrorException($message, 0, $type, $error['file'], $error['line']);
+ $exceptionHandler[0]->handle($exception);
+ }
+ }
}
diff --git a/src/Symfony/Component/HttpKernel/Debug/ExceptionHandler.php b/src/Symfony/Component/HttpKernel/Debug/ExceptionHandler.php
index 88ef3d7615..79d7d66dcc 100644
--- a/src/Symfony/Component/HttpKernel/Debug/ExceptionHandler.php
+++ b/src/Symfony/Component/HttpKernel/Debug/ExceptionHandler.php
@@ -234,6 +234,9 @@ EOF;
img { border: 0; }
#sf-resetcontent { width:970px; margin:0 auto; }
$css
+ .xdebug-error {
+ display: none;
+ }
diff --git a/src/Symfony/Component/HttpKernel/Exception/FatalErrorException.php b/src/Symfony/Component/HttpKernel/Exception/FatalErrorException.php
new file mode 100644
index 0000000000..a082f80dc0
--- /dev/null
+++ b/src/Symfony/Component/HttpKernel/Exception/FatalErrorException.php
@@ -0,0 +1,22 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Exception;
+
+/**
+ * Fatal Error Exception.
+ *
+ * @author Konstanton Myakshin
+ */
+class FatalErrorException extends \ErrorException
+{
+
+}
diff --git a/src/Symfony/Component/HttpKernel/Exception/FlattenException.php b/src/Symfony/Component/HttpKernel/Exception/FlattenException.php
index eb5e5715fa..367b549440 100644
--- a/src/Symfony/Component/HttpKernel/Exception/FlattenException.php
+++ b/src/Symfony/Component/HttpKernel/Exception/FlattenException.php
@@ -47,7 +47,7 @@ class FlattenException
$e->setStatusCode($statusCode);
$e->setHeaders($headers);
- $e->setTrace($exception->getTrace(), $exception->getFile(), $exception->getLine());
+ $e->setTraceFromException($exception);
$e->setClass(get_class($exception));
$e->setFile($exception->getFile());
$e->setLine($exception->getLine());
@@ -168,6 +168,40 @@ class FlattenException
return $this->trace;
}
+ public function setTraceFromException(\Exception $exception)
+ {
+ $trace = $exception->getTrace();
+
+ if ($exception instanceof FatalErrorException) {
+ if (function_exists('xdebug_get_function_stack')) {
+ $trace = array_slice(array_reverse(xdebug_get_function_stack()), 4);
+
+ foreach ($trace as $i => $frame) {
+ // XDebug pre 2.1.1 doesn't currently set the call type key http://bugs.xdebug.org/view.php?id=695
+ if (!isset($frame['type'])) {
+ $trace[$i]['type'] = '??';
+ }
+
+ if ('dynamic' === $trace[$i]['type']) {
+ $trace[$i]['type'] = '->';
+ } elseif ('static' === $trace[$i]['type']) {
+ $trace[$i]['type'] = '::';
+ }
+
+ // XDebug also has a different name for the parameters array
+ if (isset($frame['params']) && !isset($frame['args'])) {
+ $trace[$i]['args'] = $frame['params'];
+ unset($trace[$i]['params']);
+ }
+ }
+ } else {
+ $trace = array_slice(array_reverse($trace), 1);
+ }
+ }
+
+ $this->setTrace($trace, $exception->getFile(), $exception->getLine());
+ }
+
public function setTrace($trace, $file, $line)
{
$this->trace = array();
diff --git a/src/Symfony/Component/HttpKernel/Tests/Debug/ErrorHandlerTest.php b/src/Symfony/Component/HttpKernel/Tests/Debug/ErrorHandlerTest.php
index 0eb2d79d4c..e98d326a4b 100644
--- a/src/Symfony/Component/HttpKernel/Tests/Debug/ErrorHandlerTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/Debug/ErrorHandlerTest.php
@@ -12,7 +12,6 @@
namespace Symfony\Component\HttpKernel\Tests\Debug;
use Symfony\Component\HttpKernel\Debug\ErrorHandler;
-use Symfony\Component\HttpKernel\Debug\ErrorException;
/**
* ErrorHandlerTest
@@ -48,10 +47,10 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
$handler = ErrorHandler::register(3);
try {
- $handler->handle(1, 'foo', 'foo.php', 12, 'foo');
+ $handler->handle(111, 'foo', 'foo.php', 12, 'foo');
} catch (\ErrorException $e) {
- $this->assertSame('1: foo in foo.php line 12', $e->getMessage());
- $this->assertSame(1, $e->getSeverity());
+ $this->assertSame('111: foo in foo.php line 12', $e->getMessage());
+ $this->assertSame(111, $e->getSeverity());
$this->assertSame('foo.php', $e->getFile());
$this->assertSame(12, $e->getLine());
}
diff --git a/src/Symfony/Component/HttpKernel/Tests/Exception/FlattenExceptionTest.php b/src/Symfony/Component/HttpKernel/Tests/Exception/FlattenExceptionTest.php
index 934b44b461..d51ab6aa07 100644
--- a/src/Symfony/Component/HttpKernel/Tests/Exception/FlattenExceptionTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/Exception/FlattenExceptionTest.php
@@ -156,14 +156,14 @@ class FlattenExceptionTest extends \PHPUnit_Framework_TestCase
public function testToArray(\Exception $exception, $statusCode)
{
$flattened = FlattenException::create($exception);
- $flattened->setTrace(array(),'foo.php',123);
+ $flattened->setTrace(array(), 'foo.php', 123);
$this->assertEquals(array(
array(
'message'=> 'test',
'class'=>'Exception',
'trace'=>array(array(
- 'namespace' => '', 'short_class' => '', 'class' => '','type' => '','function' => '', 'file' => 'foo.php','line' => 123,
+ 'namespace' => '', 'short_class' => '', 'class' => '','type' => '','function' => '', 'file' => 'foo.php', 'line' => 123,
'args' => array()
)),
)