Skip to content

Commit

Permalink
[FrameworkBundle] added support for previous exceptions in the except…
Browse files Browse the repository at this point in the history
…ion pages
  • Loading branch information
fabpot committed Aug 24, 2010
1 parent 789a02d commit ec8500b
Show file tree
Hide file tree
Showing 18 changed files with 247 additions and 89 deletions.
Expand Up @@ -32,9 +32,18 @@ public function exceptionAction(ExceptionManager $manager)
{
$this['request']->setRequestFormat($manager->getFormat());

$currentContent = '';
while (false !== $content = ob_get_clean()) {
$currentContent .= $content;
}

$response = $this->render(
'FrameworkBundle:Exception:'.($this['kernel']->isDebug() ? 'exception' : 'error'),
array('manager' => $manager)
array(
'manager' => $manager,
'managers' => $manager->getLinkedManagers(),
'currentContent' => $currentContent,
)
);
$response->setStatusCode($manager->getStatusCode());

Expand Down
40 changes: 25 additions & 15 deletions src/Symfony/Bundle/FrameworkBundle/Debug/ExceptionManager.php
Expand Up @@ -27,30 +27,30 @@ class ExceptionManager
protected $exception;
protected $request;
protected $logger;
protected $currentContent;

public function __construct(\Exception $exception, Request $request, DebugLoggerInterface $logger = null)
{
$this->exception = $exception;
$this->request = $request;
$this->logger = $logger;
}

$this->currentContent = '';
while (false !== $content = ob_get_clean()) {
$this->currentContent .= $content;
public function getLinkedManagers()
{
$managers = array();
$e = $this->exception;
while ($e = $e->getPrevious()) {
$managers[] = new $this($e, $this->request);
}

return $managers;
}

public function getException()
{
return $this->exception;
}

public function getCurrentContent()
{
return $this->currentContent;
}

public function getLogger()
{
return $this->logger;
Expand Down Expand Up @@ -126,13 +126,23 @@ public function getTraces()
'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(
'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(),
'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(),
);
}

Expand Down
Expand Up @@ -92,6 +92,7 @@
<service id="templating.helper.code" class="%templating.helper.code.class%">
<tag name="templating.helper" alias="code" />
<argument>%debug.file_link_format%</argument>
<argument>%kernel.root_dir%</argument>
</service>

<service id="templating.loader" alias="templating.loader.filesystem" />
Expand Down
@@ -1,9 +1,25 @@
<?php echo json_encode(array(
<?php

$vars = array(
'error' => array(
'code' => $manager->getStatusCode(),
'message' => $manager->getMessage(),
'debug' => array(
'message' => $manager->getName(),
'exception' => array(
'name' => $manager->getName(),
'message' => $manager->getMessage(),
'traces' => $manager->getTraces(),
),
))) ?>
));

if (count($managers)) {
$vars['exceptions'] = array();
foreach ($managers as $i => $previous) {
$vars['exceptions'][] = array(
'name' => $previous->getName(),
'message' => $previous->getMessage(),
'traces' => $previous->getTraces(),
);
}
}

echo json_encode($vars);
Expand Up @@ -7,10 +7,21 @@
<?php echo $view->render('FrameworkBundle:Exception:styles') ?>
</style>
<script type="text/javascript">
function toggle(id)
{
el = document.getElementById(id); el.style.display = el.style.display == 'none' ? 'block' : 'none';
}
function toggle(id, clazz) {
el = document.getElementById(id);
current = el.style.display

if (clazz) {
var tags = document.getElementsByTagName('*');
for (i = 0; i < tags.length; i++) {
if (tags[i].className == clazz) {
tags[i].style.display = 'none';
}
}
}

el.style.display = current == 'none' ? 'block' : 'none';
}
</script>
</head>
<body>
Expand All @@ -20,33 +31,50 @@ function toggle(id)
<img src="data:image/png;base64,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" />
</div>
<div style="float: left; width: 600px">
<h2><?php echo $manager->getStatusCode() ?> <?php echo $manager->getStatusText() ?> - <?php echo $manager->getName() ?></h2>
<h1><?php echo 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>
<ul>
<?php foreach ($managers 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>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
</div>

<div style="clear: both"></div>
</div>

<div id="main">
<?php echo $view->render('FrameworkBundle:Exception:traces', array('manager' => $manager, 'position' => 0, 'count' => count($managers))) ?>

<?php foreach ($managers as $i => $previous): ?>
<?php echo $view->render('FrameworkBundle:Exception:traces', array('manager' => $previous, 'position' => $i + 1, 'count' => count($managers))) ?>
<?php endforeach; ?>

<div class="block">
<h3>
Logs <a href="#" onclick="toggle('logs'); return false;">...</a>
<?php if ($manager->countErrors()): ?>
<span class="error"><?php echo $manager->countErrors() ?> errors</span>
<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>

<div id="logs" style="display: none">
<?php echo $view->render('FrameworkBundle:Exception:logs', array('logs' => $manager->getLogs())) ?>
</div>

<h3>Stack Trace</h3>

<?php echo $view->render('FrameworkBundle:Exception:traces', array('traces' => $manager->getTraces())) ?>
</div>

<h3>Content of the Output <a href="#" onclick="toggle('content'); return false;">...</a></h3>
<div class="block">
<h3>Content of the Output <a href="#" onclick="toggle('content'); return false;">&raquo;</a></h3>

<div id="content" style="display: none">
<?php echo $manager->getCurrentContent() ?>
<?php echo $currentContent ?>
</div>

<div style="clear: both"></div>
Expand Down
@@ -1,14 +1,19 @@
[exception] <?php echo $manager->getStatusCode().' | '.$manager->getStatusText().' | '.$manager->getName() ?>
[exception] <?php echo $manager->getStatusCode().' | '.$manager->getStatusText().' | '.$manager->getName() ?>

[message] <?php echo $manager->getMessage() ?>
[message] <?php echo $manager->getMessage() ?>

<?php if (count($manager->getTraces())): ?>
[stack trace]
<?php foreach ($manager->getTraces() as $i => $trace): ?>
<?php echo $view->render('FrameworkBundle:Exception:trace.txt', array('i' => $i, 'trace' => $trace)) ?>
<?php echo $view->render('FrameworkBundle:Exception:traces', array('manager' => $manager, 'position' => 0, 'count' => count($managers))) ?>

<?php endforeach; ?>
<?php endif; ?>
<?php if (count($managers)): ?>
<?php foreach ($managers as $i => $previous): ?>
[linked exception] <?php echo $previous->getName() ?>: <?php echo $previous->getMessage() ?>

<?php echo $view->render('FrameworkBundle:Exception:traces', array('manager' => $previous, 'position' => $i + 1, 'count' => count($managers))) ?>

<?php endforeach; ?>
<?php endif; ?>
[symfony] v. <?php echo \Symfony\Framework\Kernel::VERSION ?> (symfony-project.org)
[PHP] v. <?php echo PHP_VERSION ?>

[symfony] v. <?php echo \Symfony\Framework\Kernel::VERSION ?> (symfony-project.org)
[PHP] v. <?php echo PHP_VERSION ?>
@@ -1,15 +1,13 @@
<?php echo sprintf('<?xml version="1.0" encoding="%s" ?>', $view->getCharset())."\n" ?>
<error code="<?php echo $manager->getStatusCode() ?>" message="<?php echo $manager->getStatusText() ?>">
<debug>
<name><?php echo $manager->getName() ?></name>
<message><?php echo htmlspecialchars($manager->getMessage(), ENT_QUOTES, $view->getCharset()) ?></message>
<traces>
<?php foreach ($manager->getTraces() as $i => $trace): ?>
<trace>
<?php echo $view->render('FrameworkBundle:Exception:trace.txt', array('i' => $i, 'trace' => $trace)) ?>

</trace>
<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))) ?>
</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))) ?>
</exception>
<?php endforeach; ?>
</traces>
</debug>
<?php endif; ?>
</error>
@@ -1,25 +1,41 @@
body { margin: 0; padding: 0; margin-top: 30px; background-color: #eee }
body, td, th { font: 11px Verdana, Arial, sans-serif; color: #333 }
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.2
build: 56
*/
html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}

/*
Symfony stylesheet
*/
html { background: #eee }
body { font: 11px Verdana, Arial, sans-serif; color: #333 }
strong { font-weight: bold }
em { font-style: italic }
a { color: #333 }
h1 { margin: 0; margin-top: 4px; font-weight: normal; font-size: 170%; letter-spacing: -0.03em; }
h2 { margin: 0; padding: 0; font-size: 90%; font-weight: normal; letter-spacing: -0.02em; }
h3 { margin: 0; padding: 0; margin-bottom: 10px; font-size: 110% }
ul { padding-left: 20px; list-style: decimal }
ul li { padding-bottom: 5px; margin: 0 }
ol { font-family: monospace; white-space: pre; list-style-position: inside; margin: 0; padding: 10px 0 }
ol li { margin: -5px; padding: 0 }
abbr { border-bottom: 1px dotted #000000; cursor: help }
h1 { font-size: 170%; letter-spacing: -0.03em; }
h2 { margin-top: 4px; font-size: 90%; letter-spacing: -0.02em; }
h3 { font-size: 130%; font-weight: bold; letter-spacing: -0.02em; }
h3 span { float: right; font-size: 80%; background: #eee; color: #333; padding: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }
ul { padding-left: 20px }
ul li { padding-bottom: 5px; list-style: decimal }
ol { font-family: monospace; white-space: pre; padding: 10px 0 }
ol li { margin: -5px; list-style: decimal; list-style-position: inside }
ol .selected { font-weight: bold; background-color: #ffd; padding: 2px 0 }
table.vars { padding: 0; margin: 0; border: 1px solid #999; background-color: #fff; }
table.vars th { padding: 2px; background-color: #ddd; font-weight: bold }
table.vars td { padding: 2px; font-family: monospace; white-space: pre }
p.error { padding: 10px; background-color: #f00; font-weight: bold; text-align: center; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px; }
p.error a { color: #fff }
#main { padding: 20px 25px; margin: 0; margin-bottom: 20px; border: 1px solid #ddd; background-color: #fff; text-align:left; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px; min-width: 770px; max-width: 770px }
#message { padding: 20px 25px; margin: 0; margin-bottom: 5px; border: 1px solid #ddd; text-align:left; background-color: #c8e8f3; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px; min-width: 770px; max-width: 770px }
.block { padding: 20px 25px; margin-bottom: 10px; border: 1px solid #ddd; background-color: #fff; text-align:left; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px; min-width: 770px; max-width: 770px }
.traces { display: none; margin-top: 10px }
#message { margin-top: 30px; margin-bottom: 10px; padding: 20px 25px; border: 1px solid #ddd; text-align:left; background-color: #c8e8f3; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px; min-width: 770px; max-width: 770px }
#content { border: 1px solid #ddd; margin-top: 10px; padding: 7px; overflow: auto; }
a.file_link { text-decoration: none; }
a.file_link:hover { text-decoration: underline; }
.code { overflow: auto; }
img { vertical-align: middle; }
a img { border: 0; }
.error { background-color: #f66; padding: 1px 3px; color: #111; }
.error { background-color: #f66 }
.linked ul, .linked li { padding-left: 0; display: inline }
.linked li { padding-right: 7px }
#logs { margin-top: 10px }

0 comments on commit ec8500b

Please sign in to comment.