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; namespace Symfony\Bundle\FrameworkBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\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. * This file is part of the Symfony framework.
@ -24,13 +26,14 @@ class ExceptionController extends Controller
/** /**
* Converts an Exception to a Response. * Converts an Exception to a Response.
* *
* @param ExceptionManager $manager An ExceptionManager instance * @param FlattenException $exception A FlattenException instance
* @param string $format The format to use for rendering (html, xml, ...) * @param DebugLoggerInterface $logger A DebugLoggerInterface instance
* @param Boolean $embedded Whether the rendered Response will be embedded or not * @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 * @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); $this['request']->setRequestFormat($format);
@ -42,13 +45,13 @@ class ExceptionController extends Controller
$response = $this->render( $response = $this->render(
'FrameworkBundle:Exception:'.($this['kernel']->isDebug() ? 'exception' : 'error'), 'FrameworkBundle:Exception:'.($this['kernel']->isDebug() ? 'exception' : 'error'),
array( array(
'manager' => $manager, 'exception' => new SafeDecorator($exception),
'managers' => $manager->getLinkedManagers(), 'logger' => $logger,
'currentContent' => $currentContent, 'currentContent' => $currentContent,
'embedded' => $embedded, 'embedded' => $embedded,
) )
); );
$response->setStatusCode($manager->getStatusCode()); $response->setStatusCode($exception->getStatusCode());
return $response; return $response;
} }

View File

@ -7,6 +7,7 @@ use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\HttpKernel\Log\LoggerInterface; use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Exception\FlattenException;
use Symfony\Component\HttpFoundation\Request; 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())); 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') ? $this->container->get('logger')->getDebugLogger() : null;
$logger = $this->container->has('logger.debug') ? $this->container->get('logger.debug') : null;
$attributes = array( $attributes = array(
'_controller' => $this->controller, '_controller' => $this->controller,
'manager' => new $class($exception, $logger), 'exception' => FlattenException::create($exception),
'logger' => $logger,
// when using CLI, we force the format to be TXT // when using CLI, we force the format to be TXT
'format' => 0 === strncasecmp(PHP_SAPI, 'cli', 3) ? 'txt' : $request->getRequestFormat(), '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="response_listener.class">Symfony\Component\HttpKernel\ResponseListener</parameter>
<parameter key="exception_listener.class">Symfony\Bundle\FrameworkBundle\Debug\ExceptionListener</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_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.class">Symfony\Component\HttpKernel\Cache\Esi</parameter>
<parameter key="esi_listener.class">Symfony\Component\HttpKernel\Cache\EsiListener</parameter> <parameter key="esi_listener.class">Symfony\Component\HttpKernel\Cache\EsiListener</parameter>
</parameters> </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( <?php echo json_encode(array(
'error' => array( 'error' => array(
'code' => $manager->getStatusCode(), 'code' => $exception->getStatusCode(),
'message' => $manager->getStatusText(), 'message' => $exception->getStatusText(),
))) ?> ))) ?>

View File

@ -6,7 +6,7 @@
</head> </head>
<body> <body>
<h1>Oops! An Error Occurred</h1> <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> <div>
Something is broken. Please e-mail us at [email] and let us know 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 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 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 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" ?> <?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( $vars = array(
'error' => array( 'error' => array(
'code' => $manager->getStatusCode(), 'code' => $exception->getStatusCode(),
'message' => $manager->getName(), 'message' => $exception->getMessage(),
'exception' => array( 'exception' => array(
'name' => $manager->getName(), 'name' => $exception->getClass(),
'message' => $manager->getMessage(), 'message' => $exception->getMessage(),
'traces' => $manager->getTraces(), 'trace' => $exception->getTrace(),
), ),
)); ));
if (count($managers)) { if (count($exception->getPreviouses())) {
$vars['exceptions'] = array(); $vars['exceptions'] = array();
foreach ($managers as $i => $previous) { foreach ($exception->getPreviouses() as $i => $previous) {
$vars['exceptions'][] = array( $vars['exceptions'][] = array(
'name' => $previous->getName(), 'name' => $previous->getClass(),
'message' => $previous->getMessage(), '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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" /> <img src="data:image/png;base64,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" />
</div> </div>
<div style="float: left; width: 600px"> <div style="float: left; width: 600px">
<h1><?php echo $view['code']->formatFileFromText(str_replace("\n", '<br />', htmlspecialchars($manager->getMessage(), ENT_QUOTES, $view->getCharset()))) ?></h1> <h1><?php echo $view['code']->formatFileFromText(str_replace("\n", '<br />', htmlspecialchars($exception->getMessage(), ENT_QUOTES, $view->getCharset()))) ?></h1>
<h2><strong><?php echo $manager->getStatusCode() ?></strong> <?php echo $manager->getStatusText() ?> - <?php echo $manager->getName() ?></h2> <h2><strong><?php echo $exception->getStatusCode() ?></strong> <?php echo $exception->getStatusText() ?> - <?php echo $exception->getClass() ?></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> <?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> <ul>
<?php foreach ($managers as $i => $previous): ?> <?php foreach ($exception->getPreviouses() as $i => $previous): ?>
<li> <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> </li>
<?php endforeach; ?> <?php endforeach; ?>
</ul> </ul>
@ -26,25 +27,27 @@
<div style="clear: both"></div> <div style="clear: both"></div>
</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 foreach ($exception->getPreviouses() as $i => $previous): ?>
<?php echo $view->render('FrameworkBundle:Exception:traces', array('manager' => $previous, 'position' => $i + 1, 'count' => count($managers))) ?> <?php echo $view->render('FrameworkBundle:Exception:traces', array('exception' => $previous, 'position' => $i + 1, 'count' => $previousCount)) ?>
<?php endforeach; ?> <?php endforeach; ?>
<div class="block"> <?php if (null !== $logger): ?>
<h3> <div class="block">
<?php if ($manager->countErrors()): ?> <h3>
<span class="error"><?php echo $manager->countErrors() ?> error<?php if ($manager->countErrors() > 1): ?>s<?php endif; ?></span> <?php if ($logger->countErrors()): ?>
<?php endif; ?> <span class="error"><?php echo $logger->countErrors() ?> error<?php if ($logger->countErrors() > 1): ?>s<?php endif; ?></span>
Logs <a href="#" onclick="toggle('logs'); return false;">&raquo;</a> <?php endif; ?>
</h3> 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>
<div class="block"> <div class="block">
<h3>Content of the Output <a href="#" onclick="toggle('content'); return false;">&raquo;</a></h3> <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 if ($previousCount = count($exception->getPreviouses())): ?>
<?php echo $view->render('FrameworkBundle:Exception:traces', array('manager' => $manager, 'position' => 0, 'count' => count($managers))) ?> <?php echo $view->render('FrameworkBundle:Exception:traces.txt', array('exception' => $exception, 'position' => 0, 'count' => $previousCount)) ?>
<?php endif; ?> <?php endif; ?>
<?php if (count($managers)): ?> <?php if ($previousCount): ?>
<?php foreach ($managers as $i => $previous): ?> <?php foreach ($exception->getPreviouses() as $i => $previous): ?>
[linked exception] <?php echo $previous->getName() ?>: <?php echo $previous->getMessage() ?> [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 endforeach; ?>
<?php endif; ?> <?php endif; ?>

View File

@ -1,12 +1,12 @@
<?php echo sprintf('<?xml version="1.0" encoding="%s" ?>', $view->getCharset())."\n" ?> <?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() ?>">
<exception class="<?php echo $manager->getName() ?>" message="<?php echo $manager->getMessage() ?>"> <exception class="<?php echo $exception->getClass() ?>" message="<?php echo $exception->getMessage() ?>">
<?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 = count($exception->getPreviouses())))) ?>
</exception> </exception>
<?php if (count($managers)): ?> <?php if ($previousCount): ?>
<?php foreach ($managers as $i => $previous): ?> <?php foreach ($exception->getPreviouses() as $i => $previous): ?>
<exception class="<?php echo $previous->getName() ?>" message="<?php echo $previous->getMessage() ?>"> <exception class="<?php echo $previous->getClass() ?>" message="<?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', array('exception' => $previous, 'position' => $i + 1, 'count' => $previousCount)) ?>
</exception> </exception>
<?php endforeach; ?> <?php endforeach; ?>
<?php endif; ?> <?php endif; ?>

View File

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

View File

@ -2,7 +2,7 @@
<?php if ($count > 0): ?> <?php if ($count > 0): ?>
<h3> <h3>
<span><?php echo $count - $position + 1 ?>/<?php echo $count + 1 ?></span> <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 /> <a href="#" onclick="toggle('traces_<?php echo $position ?>', 'traces'); return false;">&raquo;</a><br />
</h3> </h3>
<?php else: ?> <?php else: ?>
@ -11,7 +11,7 @@
<a id="traces_link_<?php echo $position ?>"></a> <a id="traces_link_<?php echo $position ?>"></a>
<ul class="traces" id="traces_<?php echo $position ?>" style="display: <?php echo 0 === $position ? 'block' : 'none' ?>"> <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> <li>
<?php echo $view->render('FrameworkBundle:Exception:trace', array('prefix' => $position, 'i' => $i, 'trace' => $trace)) ?> <?php echo $view->render('FrameworkBundle:Exception:trace', array('prefix' => $position, 'i' => $i, 'trace' => $trace)) ?>
</li> </li>

View File

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

View File

@ -1,5 +1,5 @@
<traces> <traces>
<?php foreach ($manager->getTraces() as $i => $trace): ?> <?php foreach ($exception->getTrace() as $i => $trace): ?>
<trace> <trace>
<?php echo $view->render('FrameworkBundle:Exception:trace.txt', array('i' => $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) public function formatArgsAsText($args)
{ {
$result = array(); $result = array();
foreach ($args as $key => $value) { foreach ($args as $key => $item) {
if (is_object($value)) { if ('object' === $item[0]) {
$formattedValue = sprintf("object('%s')", get_class($value)); $formattedValue = sprintf("object(%s)", $item[1]);
} elseif (is_array($value)) { } elseif ('array' === $item[0]) {
$formattedValue = sprintf("array(%s)", $this->formatArgs($value)); $formattedValue = sprintf("array(%s)", $this->formatArgsAsText($item[1]));
} elseif (is_string($value)) { } elseif ('string' === $item[0]) {
$formattedValue = sprintf("'%s'", $value); $formattedValue = sprintf("'%s'", $item[1]);
} elseif (null === $value) { } elseif ('null' === $item[0]) {
$formattedValue = 'null'; $formattedValue = 'null';
} elseif (false === $value) { } elseif ('boolean' === $item[0]) {
$formattedValue = 'false'; $formattedValue = strtolower(var_export($item[1], true));
} elseif (true === $value) { } elseif ('resource' === $item[0]) {
$formattedValue = 'true'; $formattedValue = 'resource';
} else { } else {
$formattedValue = $value; $formattedValue = str_replace("\n", '', var_export((string) $item[1], true));
} }
$result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue); $result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue);
@ -96,24 +96,23 @@ class CodeHelper extends Helper
public function formatArgs($args) public function formatArgs($args)
{ {
$result = array(); $result = array();
foreach ($args as $key => $value) { foreach ($args as $key => $item) {
if (is_object($value)) { if ('object' === $item[0]) {
$class = get_class($value); $parts = explode('\\', $item[1]);
$parts = explode('\\', $class);
$short = array_pop($parts); $short = array_pop($parts);
$formattedValue = sprintf("<em>object</em>(<abbr title=\"%s\">%s</abbr>)", $class, $short); $formattedValue = sprintf("<em>object</em>(<abbr title=\"%s\">%s</abbr>)", $item[1], $short);
} elseif (is_array($value)) { } elseif ('array' === $item[0]) {
$formattedValue = sprintf("<em>array</em>(%s)", $this->formatArgs($value)); $formattedValue = sprintf("<em>array</em>(%s)", $this->formatArgs($item[1]));
} elseif (is_string($value)) { } elseif ('string' === $item[0]) {
$formattedValue = sprintf("'%s'", $value); $formattedValue = sprintf("'%s'", $item[1]);
} elseif (null === $value) { } elseif ('null' === $item[0]) {
$formattedValue = '<em>null</em>'; $formattedValue = '<em>null</em>';
} elseif (false === $value) { } elseif ('boolean' === $item[0]) {
$formattedValue = '<em>false</em>'; $formattedValue = '<em>'.strtolower(var_export($item[1], true)).'</em>';
} elseif (true === $value) { } elseif ('resource' === $item[0]) {
$formattedValue = '<em>true</em>'; $formattedValue = '<em>resource</em>';
} else { } else {
$formattedValue = $value; $formattedValue = str_replace("\n", '', var_export((string) $item[1], true));
} }
$result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue); $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; 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. * 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\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\FlattenException;
/* /*
* This file is part of the Symfony framework. * This file is part of the Symfony framework.
@ -28,7 +29,7 @@ class ExceptionDataCollector extends DataCollector
{ {
if (null !== $exception) { if (null !== $exception) {
$this->data = array( $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 * @return array An array of logs
*/ */
public function getLogs(); public function getLogs();
/**
* Returns the number of errors.
*
* @return integer The number of errors
*/
public function countErrors();
} }