Commit 68908051 by Carsten Brandt

Added support for previous exceptions

PHP supports exception stacks since 5.3 so we should use it. Also Errorhandler is now able to display the stack: #297
parent 0ef40b28
......@@ -49,6 +49,10 @@ class ErrorHandler extends Component
*/
public $callStackItemView = '@yii/views/errorHandler/callStackItem.php';
/**
* @var string the path of the view file for rendering previous exceptions.
*/
public $previousExceptionView = '@yii/views/errorHandler/previousException.php';
/**
* @var \Exception the exception that is being handled currently.
*/
public $exception;
......@@ -161,6 +165,24 @@ class ErrorHandler extends Component
}
/**
* Renders the previous exception stack for a given Exception.
* @param \Exception $exception the exception whose precursors should be rendered.
* @return string HTML content of the rendered previous exceptions.
* Empty string if there are none.
*/
public function renderPreviousExceptions($exception)
{
if (($previous = $exception->getPrevious()) === null) {
return '';
}
$view = new View();
return $view->renderFile($this->previousExceptionView, array(
'exception' => $previous,
'previousHtml' => $this->renderPreviousExceptions($previous),
), $this);
}
/**
* Renders a single call stack element.
* @param string $file name where call has happened.
* @param integer $line number on which call has happened.
......
......@@ -103,7 +103,7 @@ class HttpException extends UserException
if (isset($httpCodes[$this->statusCode])) {
return $httpCodes[$this->statusCode];
} else {
return \Yii::t('yii', 'Error');
return 'Error';
}
}
}
......@@ -113,7 +113,7 @@ class Application extends \yii\base\Application
try {
return parent::runAction($route, $params);
} catch (InvalidRouteException $e) {
throw new Exception(\Yii::t('yii', 'Unknown command "{command}".', array('{command}' => $route)));
throw new Exception(\Yii::t('yii', 'Unknown command "{command}".', array('{command}' => $route)), 0, $e);
}
}
......
......@@ -1215,7 +1215,7 @@ class ActiveRecord extends Model
return $relation;
}
} catch (UnknownMethodException $e) {
throw new InvalidParamException(get_class($this) . ' has no relation named "' . $name . '".');
throw new InvalidParamException(get_class($this) . ' has no relation named "' . $name . '".', 0, $e);
}
}
......
......@@ -148,7 +148,7 @@ class Command extends \yii\base\Component
} catch (\Exception $e) {
Yii::error($e->getMessage() . "\nFailed to prepare SQL: $sql", __METHOD__);
$errorInfo = $e instanceof \PDOException ? $e->errorInfo : null;
throw new Exception($e->getMessage(), $errorInfo, (int)$e->getCode());
throw new Exception($e->getMessage(), $errorInfo, (int)$e->getCode(), $e);
}
}
}
......@@ -298,7 +298,7 @@ class Command extends \yii\base\Component
Yii::error("$message\nFailed to execute SQL: $rawSql", __METHOD__);
$errorInfo = $e instanceof \PDOException ? $e->errorInfo : null;
throw new Exception($message, $errorInfo, (int)$e->getCode());
throw new Exception($message, $errorInfo, (int)$e->getCode(), $e);
}
}
......@@ -433,7 +433,7 @@ class Command extends \yii\base\Component
$message = $e->getMessage();
Yii::error("$message\nCommand::$method() failed: $rawSql", __METHOD__);
$errorInfo = $e instanceof \PDOException ? $e->errorInfo : null;
throw new Exception($message, $errorInfo, (int)$e->getCode());
throw new Exception($message, $errorInfo, (int)$e->getCode(), $e);
}
}
......
......@@ -319,7 +319,7 @@ class Connection extends Component
Yii::endProfile($token, __METHOD__);
Yii::error("Failed to open DB connection ({$this->dsn}): " . $e->getMessage(), __METHOD__);
$message = YII_DEBUG ? 'Failed to open DB connection: ' . $e->getMessage() : 'Failed to open DB connection.';
throw new Exception($message, $e->errorInfo, (int)$e->getCode());
throw new Exception($message, $e->errorInfo, (int)$e->getCode(), $e);
}
}
}
......
......@@ -11,7 +11,6 @@
*/
$context = $this->context;
?>
<li class="<?php if (!$context->isCoreFile($file)) echo 'application'; ?> call-stack-item">
<div class="element-wrap">
<div class="element">
......
......@@ -93,6 +93,35 @@ html,body{
font-size: 20px;
text-shadow: 0 1px 0 #cacaca;
}
/* previous exceptions */
.header div.previous{
margin: 20px 20px 0 0;
}
.header div.previous div{
margin: 15px 20px 0 25px;
}
.header div.previous h1{
font-size: 20px;
margin-bottom: 10px;
}
h1 span.arrow{
display: inline-block;
-moz-transform: scale(-1, 1);
-webkit-transform: scale(-1, 1);
-o-transform: scale(-1, 1);
transform: scale(-1, 1);
filter: progid:DXImageTransform.Microsoft.BasicImage(mirror=1);
width: 30px;
text-align: center;
}
.header div.previous h2{
font-size: 15px;
margin-left: 30px;
}
.header div.previous p{
margin: 10px 0 0 30px;
color: #aaa;
}
/* call stack */
.call-stack{
......@@ -131,7 +160,7 @@ html,body{
display: inline-block;
}
.call-stack ul li .text{
color: #bbb;
color: #aaa;
}
.call-stack ul li.application .text{
color: #505050;
......@@ -139,7 +168,7 @@ html,body{
.call-stack ul li .at{
position: absolute;
right: 110px; /* 50px + 60px */
color: #bbb;
color: #aaa;
}
.call-stack ul li.application .at{
color: #505050;
......@@ -185,7 +214,7 @@ html,body{
line-height: 18px;
font-size: 14px;
font-family: Consolas, Courier New, monospace;
color: #bbb;
color: #aaa;
}
.call-stack ul li .code pre{
position: relative;
......@@ -335,6 +364,7 @@ pre .diff .change{
?></h1>
<?php endif; ?>
<h2><?php echo $context->htmlEncode($exception->getMessage()); ?></h2>
<?php echo $context->renderPreviousExceptions($exception); ?>
</div>
<div class="call-stack">
......
<div class="previous">
<h1><span class="arrow">&crarr;</span><span>Caused by: </span><?php
/**
* @var \yii\base\View $this
* @var \yii\base\Exception $exception
* @var string $previousHtml
* @var \yii\base\ErrorHandler $context
*/
$context = $this->context;
if ($exception instanceof \yii\base\Exception) {
echo '<span>' . $context->htmlEncode($exception->getName()) . '</span>';
echo ' &ndash; ' . $context->addTypeLinks(get_class($exception));
} else {
echo '<span>' . $context->htmlEncode(get_class($exception)) . '</span>';
}
?></h1>
<h2><?php echo $context->htmlEncode($exception->getMessage()); ?></h2>
<p>In <span class="file"><?php echo $exception->getFile(); ?></span> at line <span class="line"><?php echo $exception->getLine(); ?></span></p>
<?php echo $previousHtml; ?>
</div>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment