[Debug+VarDumper] Fix handling of PHP7 exception/error model
This commit is contained in:
parent
edf793ead2
commit
4dc727fa7d
@ -14,8 +14,8 @@ namespace Symfony\Component\Debug;
|
||||
use Psr\Log\LogLevel;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Debug\Exception\ContextErrorException;
|
||||
use Symfony\Component\Debug\Exception\FatalBaseException;
|
||||
use Symfony\Component\Debug\Exception\FatalErrorException;
|
||||
use Symfony\Component\Debug\Exception\FatalThrowableError;
|
||||
use Symfony\Component\Debug\Exception\OutOfMemoryException;
|
||||
use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler;
|
||||
use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler;
|
||||
@ -431,15 +431,15 @@ class ErrorHandler
|
||||
/**
|
||||
* Handles an exception by logging then forwarding it to an other handler.
|
||||
*
|
||||
* @param \Exception|\BaseException $exception An exception to handle
|
||||
* @param array $error An array as returned by error_get_last()
|
||||
* @param \Exception|\Throwable $exception An exception to handle
|
||||
* @param array $error An array as returned by error_get_last()
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function handleException($exception, array $error = null)
|
||||
{
|
||||
if (!$exception instanceof \Exception) {
|
||||
$exception = new FatalBaseException($exception);
|
||||
$exception = new FatalThrowableError($exception);
|
||||
}
|
||||
$type = $exception instanceof FatalErrorException ? $exception->getSeverity() : E_ERROR;
|
||||
|
||||
@ -451,15 +451,17 @@ class ErrorHandler
|
||||
'level' => error_reporting(),
|
||||
'stack' => $exception->getTrace(),
|
||||
);
|
||||
if ($exception instanceof FatalBaseException) {
|
||||
$error = array(
|
||||
'type' => $type,
|
||||
'message' => $message = $exception->getMessage(),
|
||||
'file' => $e['file'],
|
||||
'line' => $e['line'],
|
||||
);
|
||||
} elseif ($exception instanceof FatalErrorException) {
|
||||
$message = 'Fatal '.$exception->getMessage();
|
||||
if ($exception instanceof FatalErrorException) {
|
||||
if ($exception instanceof FatalThrowableError) {
|
||||
$error = array(
|
||||
'type' => $type,
|
||||
'message' => $message = $exception->getMessage(),
|
||||
'file' => $e['file'],
|
||||
'line' => $e['line'],
|
||||
);
|
||||
} else {
|
||||
$message = 'Fatal '.$exception->getMessage();
|
||||
}
|
||||
} elseif ($exception instanceof \ErrorException) {
|
||||
$message = 'Uncaught '.$exception->getMessage();
|
||||
if ($exception instanceof ContextErrorException) {
|
||||
@ -486,9 +488,9 @@ class ErrorHandler
|
||||
try {
|
||||
call_user_func($this->exceptionHandler, $exception);
|
||||
} catch (\Exception $handlerException) {
|
||||
$this->exceptionHandler = null;
|
||||
$this->handleException($handlerException);
|
||||
} catch (\BaseException $handlerException) {
|
||||
} catch (\Throwable $handlerException) {
|
||||
}
|
||||
if (isset($handlerException)) {
|
||||
$this->exceptionHandler = null;
|
||||
$this->handleException($handlerException);
|
||||
}
|
||||
|
@ -12,18 +12,18 @@
|
||||
namespace Symfony\Component\Debug\Exception;
|
||||
|
||||
/**
|
||||
* Base Fatal Error Exception.
|
||||
* Fatal Throwable Error.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class FatalBaseException extends FatalErrorException
|
||||
class FatalThrowableError extends FatalErrorException
|
||||
{
|
||||
public function __construct(\BaseException $e)
|
||||
public function __construct(\Throwable $e)
|
||||
{
|
||||
if ($e instanceof \ParseException) {
|
||||
if ($e instanceof \ParseError) {
|
||||
$message = 'Parse error: '.$e->getMessage();
|
||||
$severity = E_PARSE;
|
||||
} elseif ($e instanceof \TypeException) {
|
||||
} elseif ($e instanceof \TypeError) {
|
||||
$message = 'Type error: '.$e->getMessage();
|
||||
$severity = E_RECOVERABLE_ERROR;
|
||||
} else {
|
@ -40,27 +40,14 @@ class ExceptionCaster
|
||||
E_STRICT => 'E_STRICT',
|
||||
);
|
||||
|
||||
public static function castError(\Error $e, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
return $e instanceof \Exception ? $a : self::filterExceptionArray($a, "\0Error\0");
|
||||
}
|
||||
|
||||
public static function castException(\Exception $e, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$xPrefix = PHP_VERSION_ID >= 70000 ? "\0BaseException\0" : "\0Exception\0";
|
||||
if (isset($a[$xPrefix.'trace'])) {
|
||||
$trace = $a[$xPrefix.'trace'];
|
||||
unset($a[$xPrefix.'trace']); // Ensures the trace is always last
|
||||
} else {
|
||||
$trace = array();
|
||||
}
|
||||
|
||||
static::filterTrace($trace, static::$traceArgs);
|
||||
|
||||
if (null !== $trace) {
|
||||
$a[$xPrefix.'trace'] = $trace;
|
||||
}
|
||||
if (empty($a[$xPrefix.'previous'])) {
|
||||
unset($a[$xPrefix.'previous']);
|
||||
}
|
||||
unset($a[$xPrefix.'string'], $a["\0+\0xdebug_message"], $a["\0+\0__destructorException"]);
|
||||
|
||||
return $a;
|
||||
return self::filterExceptionArray($a, "\0Exception\0");
|
||||
}
|
||||
|
||||
public static function castErrorException(\ErrorException $e, array $a, Stub $stub, $isNested)
|
||||
@ -75,7 +62,7 @@ class ExceptionCaster
|
||||
public static function castThrowingCasterException(ThrowingCasterException $e, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
$prefix = "\0*\0";
|
||||
$xPrefix = PHP_VERSION_ID >= 70000 ? "\0BaseException\0" : "\0Exception\0";
|
||||
$xPrefix = "\0Exception\0";
|
||||
|
||||
if (isset($a[$xPrefix.'previous'], $a[$xPrefix.'trace'][0])) {
|
||||
$b = (array) $a[$xPrefix.'previous'];
|
||||
@ -123,4 +110,26 @@ class ExceptionCaster
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function filterExceptionArray(array $a, $xPrefix)
|
||||
{
|
||||
if (isset($a[$xPrefix.'trace'])) {
|
||||
$trace = $a[$xPrefix.'trace'];
|
||||
unset($a[$xPrefix.'trace']); // Ensures the trace is always last
|
||||
} else {
|
||||
$trace = array();
|
||||
}
|
||||
|
||||
static::filterTrace($trace, static::$traceArgs);
|
||||
|
||||
if (null !== $trace) {
|
||||
$a[$xPrefix.'trace'] = $trace;
|
||||
}
|
||||
if (empty($a[$xPrefix.'previous'])) {
|
||||
unset($a[$xPrefix.'previous']);
|
||||
}
|
||||
unset($a[$xPrefix.'string'], $a["\0+\0xdebug_message"], $a["\0+\0__destructorException"]);
|
||||
|
||||
return $a;
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
|
||||
'ErrorException' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castErrorException',
|
||||
'Exception' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castException',
|
||||
'Error' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castError',
|
||||
'Symfony\Component\DependencyInjection\ContainerInterface' => 'Symfony\Component\VarDumper\Caster\StubCaster::cutInternals',
|
||||
'Symfony\Component\VarDumper\Exception\ThrowingCasterException' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castThrowingCasterException',
|
||||
|
||||
|
Reference in New Issue
Block a user