Browse Source

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
tags/2.0.0-beta
Carsten Brandt 12 years ago
parent
commit
689080519e
  1. 22
      framework/yii/base/ErrorHandler.php
  2. 2
      framework/yii/base/HttpException.php
  3. 2
      framework/yii/console/Application.php
  4. 2
      framework/yii/db/ActiveRecord.php
  5. 6
      framework/yii/db/Command.php
  6. 2
      framework/yii/db/Connection.php
  7. 1
      framework/yii/views/errorHandler/callStackItem.php
  8. 36
      framework/yii/views/errorHandler/main.php
  9. 20
      framework/yii/views/errorHandler/previousException.php

22
framework/yii/base/ErrorHandler.php

@ -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.

2
framework/yii/base/HttpException.php

@ -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';
}
}
}

2
framework/yii/console/Application.php

@ -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);
}
}

2
framework/yii/db/ActiveRecord.php

@ -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);
}
}

6
framework/yii/db/Command.php

@ -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);
}
}

2
framework/yii/db/Connection.php

@ -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);
}
}
}

1
framework/yii/views/errorHandler/callStackItem.php

@ -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">

36
framework/yii/views/errorHandler/main.php

@ -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">

20
framework/yii/views/errorHandler/previousException.php

@ -0,0 +1,20 @@
<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>
Loading…
Cancel
Save