refactored exception management (removed the ExceptionManager)

This commit is contained in:
Fabien Potencier 2010-08-29 11:52:55 +02:00
parent 72db4c7342
commit 0208800459
28 changed files with 298 additions and 239 deletions

View File

@ -3,7 +3,9 @@
namespace Symfony\Bundle\FrameworkBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Bundle\FrameworkBundle\Debug\ExceptionManager;
use Symfony\Component\HttpKernel\Exception\FlattenException;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
use Symfony\Component\OutputEscaper\SafeDecorator;
/*
* This file is part of the Symfony framework.
@ -24,13 +26,14 @@ class ExceptionController extends Controller
/**
* Converts an Exception to a Response.
*
* @param ExceptionManager $manager An ExceptionManager instance
* @param string $format The format to use for rendering (html, xml, ...)
* @param Boolean $embedded Whether the rendered Response will be embedded or not
* @param FlattenException $exception A FlattenException instance
* @param DebugLoggerInterface $logger A DebugLoggerInterface instance
* @param string $format The format to use for rendering (html, xml, ...)
* @param Boolean $embedded Whether the rendered Response will be embedded or not
*
* @throws \InvalidArgumentException When the exception template does not exist
*/
public function exceptionAction(ExceptionManager $manager, $format, $embedded = false)
public function exceptionAction(FlattenException $exception, DebugLoggerInterface $logger, $format, $embedded = false)
{
$this['request']->setRequestFormat($format);
@ -42,13 +45,13 @@ class ExceptionController extends Controller
$response = $this->render(
'FrameworkBundle:Exception:'.($this['kernel']->isDebug() ? 'exception' : 'error'),
array(
'manager' => $manager,
'managers' => $manager->getLinkedManagers(),
'exception' => new SafeDecorator($exception),
'logger' => $logger,
'currentContent' => $currentContent,
'embedded' => $embedded,
)
);
$response->setStatusCode($manager->getStatusCode());
$response->setStatusCode($exception->getStatusCode());
return $response;
}

View File

@ -7,6 +7,7 @@ use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Exception\FlattenException;
use Symfony\Component\HttpFoundation\Request;
/*
@ -62,12 +63,12 @@ class ExceptionListener
error_log(sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine()));
}
$class = $this->container->getParameter('exception_manager.class');
$logger = $this->container->has('logger.debug') ? $this->container->get('logger.debug') : null;
$logger = $this->container->has('logger') ? $this->container->get('logger')->getDebugLogger() : null;
$attributes = array(
'_controller' => $this->controller,
'manager' => new $class($exception, $logger),
'exception' => FlattenException::create($exception),
'logger' => $logger,
// when using CLI, we force the format to be TXT
'format' => 0 === strncasecmp(PHP_SAPI, 'cli', 3) ? 'txt' : $request->getRequestFormat(),
);

View File

@ -1,136 +0,0 @@
<?php
namespace Symfony\Bundle\FrameworkBundle\Debug;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
/**
* ExceptionManager.
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class ExceptionManager
{
protected $exception;
protected $logger;
public function __construct(\Exception $exception, DebugLoggerInterface $logger = null)
{
$this->exception = $exception;
$this->logger = $logger;
}
public function getLinkedManagers()
{
$managers = array();
$e = $this->exception;
while ($e = $e->getPrevious()) {
$managers[] = new $this($e);
}
return $managers;
}
public function getException()
{
return $this->exception;
}
public function getLogger()
{
return $this->logger;
}
public function getLogs()
{
return null === $this->logger ? array() : $this->logger->getLogs();
}
public function countErrors()
{
if (null === $this->logger) {
return 0;
}
$errors = 0;
foreach ($this->logger->getLogs() as $log) {
if ('ERR' === $log['priorityName']) {
++$errors;
}
}
return $errors;
}
public function getStatusCode()
{
return $this->exception instanceof HttpException ? $this->exception->getCode() : 500;
}
public function getStatusText()
{
return Response::$statusTexts[$this->getStatusCode()];
}
public function getMessage()
{
return null === $this->exception->getMessage() ? 'n/a' : $this->exception->getMessage();
}
public function getName()
{
return get_class($this->exception);
}
/**
* Returns an array of exception traces.
*
* @return array An array of traces
*/
public function getTraces()
{
$traces = array();
$traces[] = array(
'class' => '',
'type' => '',
'function' => '',
'file' => $this->exception->getFile(),
'line' => $this->exception->getLine(),
'args' => array(),
);
foreach ($this->exception->getTrace() as $entry) {
$class = '';
$namespace = '';
if (isset($entry['class'])) {
$parts = explode('\\', $entry['class']);
$class = array_pop($parts);
$namespace = implode('\\', $parts);
}
$traces[] = array(
'namespace' => $namespace,
'short_class' => $class,
'class' => isset($entry['class']) ? $entry['class'] : '',
'type' => isset($entry['type']) ? $entry['type'] : '',
'function' => $entry['function'],
'file' => isset($entry['file']) ? $entry['file'] : null,
'line' => isset($entry['line']) ? $entry['line'] : null,
'args' => isset($entry['args']) ? $entry['args'] : array(),
);
}
return $traces;
}
}

View File

@ -11,7 +11,6 @@
<parameter key="response_listener.class">Symfony\Component\HttpKernel\ResponseListener</parameter>
<parameter key="exception_listener.class">Symfony\Bundle\FrameworkBundle\Debug\ExceptionListener</parameter>
<parameter key="exception_listener.controller">Symfony\Bundle\FrameworkBundle\Controller\ExceptionController::exceptionAction</parameter>
<parameter key="exception_manager.class">Symfony\Bundle\FrameworkBundle\Debug\ExceptionManager</parameter>
<parameter key="esi.class">Symfony\Component\HttpKernel\Cache\Esi</parameter>
<parameter key="esi_listener.class">Symfony\Component\HttpKernel\Cache\EsiListener</parameter>
</parameters>

View File

@ -1 +1 @@
<?php echo $view->render('FrameworkBundle:Exception:error.xml', array('manager' => $manager)) ?>
<?php echo $view->render('FrameworkBundle:Exception:error.xml', array('exception' => $exception)) ?>

View File

@ -1 +1 @@
<?php echo $view->render('FrameworkBundle:Exception:error.js', array('manager' => $manager)) ?>
<?php echo $view->render('FrameworkBundle:Exception:error.js', array('exception' => $exception)) ?>

View File

@ -1,3 +1,3 @@
/*
<?php echo $manager->getStatusCode().' '.$manager->getStatusText()."\n" ?>
<?php echo $exception->getStatusCode().' '.$exception->getStatusText()."\n" ?>
*/

View File

@ -1,5 +1,5 @@
<?php echo json_encode(array(
'error' => array(
'code' => $manager->getStatusCode(),
'message' => $manager->getStatusText(),
'code' => $exception->getStatusCode(),
'message' => $exception->getStatusText(),
))) ?>

View File

@ -6,7 +6,7 @@
</head>
<body>
<h1>Oops! An Error Occurred</h1>
<h2>The server returned a "<?php echo $manager->getStatusCode() ?> <?php echo $manager->getStatusText() ?>".</h2>
<h2>The server returned a "<?php echo $exception->getStatusCode() ?> <?php echo $exception->getStatusText() ?>".</h2>
<div>
Something is broken. Please e-mail us at [email] and let us know

View File

@ -1 +1 @@
<?php echo $view->render('FrameworkBundle:Exception:error.xml', array('manager' => $manager)) ?>
<?php echo $view->render('FrameworkBundle:Exception:error.xml', array('exception' => $exception)) ?>

View File

@ -1,7 +1,7 @@
Oops! An Error Occurred
=======================
The server returned a "<?php echo $manager->getStatusCode() ?> <?php echo $manager->getStatusText() ?>".
The server returned a "<?php echo $exception->getStatusCode() ?> <?php echo $exception->getStatusText() ?>".
Please e-mail us at [email] and let us know what you were doing when this
error occurred. We will fix it as soon as possible. Sorry for any

View File

@ -1,2 +1,2 @@
<?php echo sprintf('<?xml version="1.0" encoding="%s" ?>', $view->getCharset())."\n" ?>
<error code="<?php echo $manager->getStatusCode() ?>" message="<?php echo $manager->getStatusText() ?>" />
<error code="<?php echo $exception->getStatusCode() ?>" message="<?php echo $exception->getStatusText() ?>" />

View File

@ -1 +1 @@
<?php echo $view->render('FrameworkBundle:Exception:exception.xml', array('manager' => $manager)) ?>
<?php echo $view->render('FrameworkBundle:Exception:exception.xml', array('exception' => $exception)) ?>

View File

@ -1,3 +1,3 @@
/*
<?php echo $view->render('FrameworkBundle:Exception:exception.txt', array('manager' => $manager)) ?>
<?php echo $view->render('FrameworkBundle:Exception:exception.txt', array('exception' => $exception)) ?>
*/

View File

@ -1,3 +1,3 @@
/*
<?php echo $view->render('FrameworkBundle:Exception:exception.txt', array('manager' => $manager)) ?>
<?php echo $view->render('FrameworkBundle:Exception:exception.txt', array('exception' => $exception)) ?>
*/

View File

@ -2,22 +2,22 @@
$vars = array(
'error' => array(
'code' => $manager->getStatusCode(),
'message' => $manager->getName(),
'code' => $exception->getStatusCode(),
'message' => $exception->getMessage(),
'exception' => array(
'name' => $manager->getName(),
'message' => $manager->getMessage(),
'traces' => $manager->getTraces(),
'name' => $exception->getClass(),
'message' => $exception->getMessage(),
'trace' => $exception->getTrace(),
),
));
if (count($managers)) {
if (count($exception->getPreviouses())) {
$vars['exceptions'] = array();
foreach ($managers as $i => $previous) {
foreach ($exception->getPreviouses() as $i => $previous) {
$vars['exceptions'][] = array(
'name' => $previous->getName(),
'name' => $previous->getClass(),
'message' => $previous->getMessage(),
'traces' => $previous->getTraces(),
'trace' => $previous->getTrace(),
);
}
}

View File

@ -8,14 +8,15 @@
<img src="data:image/png;base64,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" />
</div>
<div style="float: left; width: 600px">
<h1><?php echo $view['code']->formatFileFromText(str_replace("\n", '<br />', htmlspecialchars($manager->getMessage(), ENT_QUOTES, $view->getCharset()))) ?></h1>
<h2><strong><?php echo $manager->getStatusCode() ?></strong> <?php echo $manager->getStatusText() ?> - <?php echo $manager->getName() ?></h2>
<?php if (count($managers)): ?>
<div class="linked"><span><strong><?php echo count($managers) ?></strong> linked Exception<?php if (count($managers) > 1): ?>s<?php endif; ?>:</span>
<h1><?php echo $view['code']->formatFileFromText(str_replace("\n", '<br />', htmlspecialchars($exception->getMessage(), ENT_QUOTES, $view->getCharset()))) ?></h1>
<h2><strong><?php echo $exception->getStatusCode() ?></strong> <?php echo $exception->getStatusText() ?> - <?php echo $exception->getClass() ?></h2>
<?php if ($previousCount = count($exception->getPreviouses())): ?>
<div class="linked"><span><strong><?php echo $previousCount ?></strong> linked Exception<?php if ($previousCount > 1): ?>s<?php endif; ?>:</span>
<ul>
<?php foreach ($managers as $i => $previous): ?>
<?php foreach ($exception->getPreviouses() as $i => $previous): ?>
<li>
<?php echo $previous->getName() ?> <a href="#traces_link_<?php echo $i + 1 ?>" onclick="toggle('traces_<?php echo $i + 1 ?>', 'traces');">&raquo;</a>
<?php echo $previous->getClass() ?> <a href="#traces_link_<?php echo $i + 1 ?>" onclick="toggle('traces_<?php echo $i + 1 ?>', 'traces');">&raquo;</a>
</li>
<?php endforeach; ?>
</ul>
@ -26,25 +27,27 @@
<div style="clear: both"></div>
</div>
<?php echo $view->render('FrameworkBundle:Exception:traces', array('manager' => $manager, 'position' => 0, 'count' => count($managers))) ?>
<?php echo $view->render('FrameworkBundle:Exception:traces', array('exception' => $exception, 'position' => 0, 'count' => $previousCount)) ?>
<?php foreach ($managers as $i => $previous): ?>
<?php echo $view->render('FrameworkBundle:Exception:traces', array('manager' => $previous, 'position' => $i + 1, 'count' => count($managers))) ?>
<?php foreach ($exception->getPreviouses() as $i => $previous): ?>
<?php echo $view->render('FrameworkBundle:Exception:traces', array('exception' => $previous, 'position' => $i + 1, 'count' => $previousCount)) ?>
<?php endforeach; ?>
<div class="block">
<h3>
<?php if ($manager->countErrors()): ?>
<span class="error"><?php echo $manager->countErrors() ?> error<?php if ($manager->countErrors() > 1): ?>s<?php endif; ?></span>
<?php endif; ?>
Logs <a href="#" onclick="toggle('logs'); return false;">&raquo;</a>
</h3>
<?php if (null !== $logger): ?>
<div class="block">
<h3>
<?php if ($logger->countErrors()): ?>
<span class="error"><?php echo $logger->countErrors() ?> error<?php if ($logger->countErrors() > 1): ?>s<?php endif; ?></span>
<?php endif; ?>
Logs <a href="#" onclick="toggle('logs'); return false;">&raquo;</a>
</h3>
<div id="logs" style="display: none">
<?php echo $view->render('FrameworkBundle:Exception:logs', array('logs' => $logger->getLogs())) ?>
</div>
<div id="logs" style="display: none">
<?php echo $view->render('FrameworkBundle:Exception:logs', array('logs' => $manager->getLogs())) ?>
</div>
</div>
<?php endif; ?>
<div class="block">
<h3>Content of the Output <a href="#" onclick="toggle('content'); return false;">&raquo;</a></h3>

View File

@ -1,16 +1,16 @@
[exception] <?php echo $manager->getStatusCode().' | '.$manager->getStatusText().' | '.$manager->getName() ?>
[exception] <?php echo $exception->getStatusCode().' | '.$exception->getStatusText().' | '.$exception->getClass() ?>
[message] <?php echo $manager->getMessage() ?>
[message] <?php echo $exception->getMessage() ?>
<?php if (count($manager->getTraces())): ?>
<?php echo $view->render('FrameworkBundle:Exception:traces', array('manager' => $manager, 'position' => 0, 'count' => count($managers))) ?>
<?php if ($previousCount = count($exception->getPreviouses())): ?>
<?php echo $view->render('FrameworkBundle:Exception:traces.txt', array('exception' => $exception, 'position' => 0, 'count' => $previousCount)) ?>
<?php endif; ?>
<?php if (count($managers)): ?>
<?php foreach ($managers as $i => $previous): ?>
[linked exception] <?php echo $previous->getName() ?>: <?php echo $previous->getMessage() ?>
<?php if ($previousCount): ?>
<?php foreach ($exception->getPreviouses() as $i => $previous): ?>
[linked exception] <?php echo $previous->getClass() ?>: <?php echo $previous->getMessage() ?>
<?php echo $view->render('FrameworkBundle:Exception:traces', array('manager' => $previous, 'position' => $i + 1, 'count' => count($managers))) ?>
<?php echo $view->render('FrameworkBundle:Exception:traces.txt', array('exception' => $previous, 'position' => $i + 1, 'count' => $previousCount)) ?>
<?php endforeach; ?>
<?php endif; ?>

View File

@ -1,12 +1,12 @@
<?php echo sprintf('<?xml version="1.0" encoding="%s" ?>', $view->getCharset())."\n" ?>
<error code="<?php echo $manager->getStatusCode() ?>" message="<?php echo $manager->getStatusText() ?>">
<exception class="<?php echo $manager->getName() ?>" message="<?php echo $manager->getMessage() ?>">
<?php echo $view->render('FrameworkBundle:Exception:traces', array('manager' => $manager, 'position' => 0, 'count' => count($managers))) ?>
<error code="<?php echo $exception->getStatusCode() ?>" message="<?php echo $exception->getStatusText() ?>">
<exception class="<?php echo $exception->getClass() ?>" message="<?php echo $exception->getMessage() ?>">
<?php echo $view->render('FrameworkBundle:Exception:traces', array('exception' => $exception, 'position' => 0, 'count' => ($previousCount = count($exception->getPreviouses())))) ?>
</exception>
<?php if (count($managers)): ?>
<?php foreach ($managers as $i => $previous): ?>
<exception class="<?php echo $previous->getName() ?>" message="<?php echo $previous->getMessage() ?>">
<?php echo $view->render('FrameworkBundle:Exception:traces', array('manager' => $previous, 'position' => $i + 1, 'count' => count($managers))) ?>
<?php if ($previousCount): ?>
<?php foreach ($exception->getPreviouses() as $i => $previous): ?>
<exception class="<?php echo $previous->getClass() ?>" message="<?php echo $previous->getMessage() ?>">
<?php echo $view->render('FrameworkBundle:Exception:traces', array('exception' => $previous, 'position' => $i + 1, 'count' => $previousCount)) ?>
</exception>
<?php endforeach; ?>
<?php endif; ?>

View File

@ -2,7 +2,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $view->getCharset() ?>"/>
<title><?php echo htmlspecialchars($manager->getMessage(), ENT_QUOTES, $view->getCharset()) ?> (<?php echo $manager->getStatusCode() ?> <?php echo $manager->getStatusText() ?>)</title>
<title><?php echo htmlspecialchars($exception->getMessage(), ENT_QUOTES, $view->getCharset()) ?> (<?php echo $exception->getStatusCode() ?> <?php echo $exception->getStatusText() ?>)</title>
<style type="text/css">
html { background: #eee }
body { font: 11px Verdana, Arial, sans-serif; color: #333 }

View File

@ -2,7 +2,7 @@
<?php if ($count > 0): ?>
<h3>
<span><?php echo $count - $position + 1 ?>/<?php echo $count + 1 ?></span>
<?php echo $manager->getName() ?>: <?php echo str_replace("\n", '<br />', htmlspecialchars($manager->getMessage(), ENT_QUOTES, $view->getCharset())) ?>
<?php echo $exception->getClass() ?>: <?php echo str_replace("\n", '<br />', htmlspecialchars($exception->getMessage(), ENT_QUOTES, $view->getCharset())) ?>
<a href="#" onclick="toggle('traces_<?php echo $position ?>', 'traces'); return false;">&raquo;</a><br />
</h3>
<?php else: ?>
@ -11,7 +11,7 @@
<a id="traces_link_<?php echo $position ?>"></a>
<ul class="traces" id="traces_<?php echo $position ?>" style="display: <?php echo 0 === $position ? 'block' : 'none' ?>">
<?php foreach ($manager->getTraces() as $i => $trace): ?>
<?php foreach ($exception->getTrace() as $i => $trace): ?>
<li>
<?php echo $view->render('FrameworkBundle:Exception:trace', array('prefix' => $position, 'i' => $i, 'trace' => $trace)) ?>
</li>

View File

@ -1,5 +1,5 @@
<?php if (count($manager->getTraces())): ?>
<?php foreach ($manager->getTraces() as $i => $trace): ?>
<?php if (count($exception->getTrace())): ?>
<?php foreach ($exception->getTrace() as $i => $trace): ?>
<?php echo $view->render('FrameworkBundle:Exception:trace.txt', array('i' => $i, 'trace' => $trace)) ?>
<?php endforeach; ?>

View File

@ -1,5 +1,5 @@
<traces>
<?php foreach ($manager->getTraces() as $i => $trace): ?>
<?php foreach ($exception->getTrace() as $i => $trace): ?>
<trace>
<?php echo $view->render('FrameworkBundle:Exception:trace.txt', array('i' => $i, 'trace' => $trace)) ?>

View File

@ -45,21 +45,21 @@ class CodeHelper extends Helper
public function formatArgsAsText($args)
{
$result = array();
foreach ($args as $key => $value) {
if (is_object($value)) {
$formattedValue = sprintf("object('%s')", get_class($value));
} elseif (is_array($value)) {
$formattedValue = sprintf("array(%s)", $this->formatArgs($value));
} elseif (is_string($value)) {
$formattedValue = sprintf("'%s'", $value);
} elseif (null === $value) {
foreach ($args as $key => $item) {
if ('object' === $item[0]) {
$formattedValue = sprintf("object(%s)", $item[1]);
} elseif ('array' === $item[0]) {
$formattedValue = sprintf("array(%s)", $this->formatArgsAsText($item[1]));
} elseif ('string' === $item[0]) {
$formattedValue = sprintf("'%s'", $item[1]);
} elseif ('null' === $item[0]) {
$formattedValue = 'null';
} elseif (false === $value) {
$formattedValue = 'false';
} elseif (true === $value) {
$formattedValue = 'true';
} elseif ('boolean' === $item[0]) {
$formattedValue = strtolower(var_export($item[1], true));
} elseif ('resource' === $item[0]) {
$formattedValue = 'resource';
} else {
$formattedValue = $value;
$formattedValue = str_replace("\n", '', var_export((string) $item[1], true));
}
$result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue);
@ -96,24 +96,23 @@ class CodeHelper extends Helper
public function formatArgs($args)
{
$result = array();
foreach ($args as $key => $value) {
if (is_object($value)) {
$class = get_class($value);
$parts = explode('\\', $class);
foreach ($args as $key => $item) {
if ('object' === $item[0]) {
$parts = explode('\\', $item[1]);
$short = array_pop($parts);
$formattedValue = sprintf("<em>object</em>(<abbr title=\"%s\">%s</abbr>)", $class, $short);
} elseif (is_array($value)) {
$formattedValue = sprintf("<em>array</em>(%s)", $this->formatArgs($value));
} elseif (is_string($value)) {
$formattedValue = sprintf("'%s'", $value);
} elseif (null === $value) {
$formattedValue = sprintf("<em>object</em>(<abbr title=\"%s\">%s</abbr>)", $item[1], $short);
} elseif ('array' === $item[0]) {
$formattedValue = sprintf("<em>array</em>(%s)", $this->formatArgs($item[1]));
} elseif ('string' === $item[0]) {
$formattedValue = sprintf("'%s'", $item[1]);
} elseif ('null' === $item[0]) {
$formattedValue = '<em>null</em>';
} elseif (false === $value) {
$formattedValue = '<em>false</em>';
} elseif (true === $value) {
$formattedValue = '<em>true</em>';
} elseif ('boolean' === $item[0]) {
$formattedValue = '<em>'.strtolower(var_export($item[1], true)).'</em>';
} elseif ('resource' === $item[0]) {
$formattedValue = '<em>resource</em>';
} else {
$formattedValue = $value;
$formattedValue = str_replace("\n", '', var_export((string) $item[1], true));
}
$result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue);

View File

@ -31,6 +31,21 @@ class DebugLogger extends AbstractWriter implements DebugLoggerInterface
return $this->logs;
}
/**
* {@inheritdoc}
*/
public function countErrors()
{
$count = 0;
foreach ($this->getLogs() as $log) {
if ('ERR' === $log['priorityName']) {
++$count;
}
}
return $count;
}
/**
* Write a message to the log.
*

View File

@ -4,6 +4,7 @@ namespace Symfony\Component\HttpKernel\DataCollector;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\FlattenException;
/*
* This file is part of the Symfony framework.
@ -28,7 +29,7 @@ class ExceptionDataCollector extends DataCollector
{
if (null !== $exception) {
$this->data = array(
'exception' => $exception,
'exception' => FlattenException::create($exception),
);
}
}

View File

@ -0,0 +1,167 @@
<?php
namespace Symfony\Component\HttpKernel\Exception;
use Symfony\Component\HttpFoundation\Response;
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
/**
* FlattenException wraps a PHP Exception to be able to serialize it.
*
* Basically, this class removes all objects from the trace.
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class FlattenException
{
protected $message;
protected $code;
protected $previous;
protected $trace;
protected $class;
static public function create(\Exception $exception)
{
$e = new static();
$e->setMessage($exception->getMessage());
$e->setCode($exception->getCode());
$e->setTrace($exception->getTrace(), $exception->getFile(), $exception->getLine());
$e->setClass(get_class($exception));
if ($exception->getPrevious()) {
$e->setPrevious(static::create($exception->getPrevious()));
}
return $e;
}
public function getStatusCode()
{
return $this->getClass() instanceof HttpException ? $this->getCode() : 500;
}
public function getStatusText()
{
return Response::$statusTexts[$this->getStatusCode()];
}
public function getClass()
{
return $this->class;
}
public function setClass($class)
{
$this->class = $class;
}
public function getMessage()
{
return $this->message;
}
public function setMessage($message)
{
$this->message = $message;
}
public function getCode()
{
return $this->code;
}
public function setCode($code)
{
$this->code = $code;
}
public function getPrevious()
{
return $this->previous;
}
public function setPrevious(FlattenException $previous)
{
$this->previous = $previous;
}
public function getPreviouses()
{
$exceptions = array();
$e = $this;
while ($e = $e->getPrevious()) {
$exceptions[] = $e;
}
return $exceptions;
}
public function getTrace()
{
return $this->trace;
}
public function setTrace($trace, $file, $line)
{
$this->trace = array();
$this->trace[] = array(
'namespace' => '',
'short_class' => '',
'class' => '',
'type' => '',
'function' => '',
'file' => $file,
'line' => $line,
'args' => array(),
);
foreach ($trace as $entry) {
$class = '';
$namespace = '';
if (isset($entry['class'])) {
$parts = explode('\\', $entry['class']);
$class = array_pop($parts);
$namespace = implode('\\', $parts);
}
$this->trace[] = array(
'namespace' => $namespace,
'short_class' => $class,
'class' => isset($entry['class']) ? $entry['class'] : '',
'type' => isset($entry['type']) ? $entry['type'] : '',
'function' => $entry['function'],
'file' => isset($entry['file']) ? $entry['file'] : null,
'line' => isset($entry['line']) ? $entry['line'] : null,
'args' => isset($entry['args']) ? $this->flattenArgs($entry['args']) : array(),
);
}
}
protected function flattenArgs($args)
{
$result = array();
foreach ($args as $key => $value) {
if (is_object($value)) {
$result[$key] = array('object', get_class($value));
} elseif (is_array($value)) {
$result[$key] = array('array', $this->flattenArgs($value));
} elseif (null === $value) {
$result[$key] = array('null', null);
} elseif (is_bool($value)) {
$result[$key] = array('boolean', $value);
} elseif (is_resource($value)) {
$result[$key] = array('resource', '');
} else {
$result[$key] = array('string', (string) $value);
}
}
return $result;
}
}

View File

@ -27,4 +27,11 @@ interface DebugLoggerInterface
* @return array An array of logs
*/
public function getLogs();
/**
* Returns the number of errors.
*
* @return integer The number of errors
*/
public function countErrors();
}