mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-17 06:48:59 +08:00
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
This commit is contained in:
@@ -48,6 +48,10 @@ class ErrorHandler extends Component
|
|||||||
* @var string the path of the view file for rendering exceptions and errors call stack element.
|
* @var string the path of the view file for rendering exceptions and errors call stack element.
|
||||||
*/
|
*/
|
||||||
public $callStackItemView = '@yii/views/errorHandler/callStackItem.php';
|
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.
|
* @var \Exception the exception that is being handled currently.
|
||||||
*/
|
*/
|
||||||
@@ -160,6 +164,24 @@ class ErrorHandler extends Component
|
|||||||
return '<a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#' . (int)$statusCode .'" target="_blank">HTTP ' . (int)$statusCode . ' – ' . $statusDescription . '</a>';
|
return '<a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#' . (int)$statusCode .'" target="_blank">HTTP ' . (int)$statusCode . ' – ' . $statusDescription . '</a>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Renders a single call stack element.
|
||||||
* @param string $file name where call has happened.
|
* @param string $file name where call has happened.
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ class HttpException extends UserException
|
|||||||
if (isset($httpCodes[$this->statusCode])) {
|
if (isset($httpCodes[$this->statusCode])) {
|
||||||
return $httpCodes[$this->statusCode];
|
return $httpCodes[$this->statusCode];
|
||||||
} else {
|
} else {
|
||||||
return \Yii::t('yii', 'Error');
|
return 'Error';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ class Application extends \yii\base\Application
|
|||||||
try {
|
try {
|
||||||
return parent::runAction($route, $params);
|
return parent::runAction($route, $params);
|
||||||
} catch (InvalidRouteException $e) {
|
} 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;
|
return $relation;
|
||||||
}
|
}
|
||||||
} catch (UnknownMethodException $e) {
|
} 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) {
|
} catch (\Exception $e) {
|
||||||
Yii::error($e->getMessage() . "\nFailed to prepare SQL: $sql", __METHOD__);
|
Yii::error($e->getMessage() . "\nFailed to prepare SQL: $sql", __METHOD__);
|
||||||
$errorInfo = $e instanceof \PDOException ? $e->errorInfo : null;
|
$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__);
|
Yii::error("$message\nFailed to execute SQL: $rawSql", __METHOD__);
|
||||||
|
|
||||||
$errorInfo = $e instanceof \PDOException ? $e->errorInfo : null;
|
$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();
|
$message = $e->getMessage();
|
||||||
Yii::error("$message\nCommand::$method() failed: $rawSql", __METHOD__);
|
Yii::error("$message\nCommand::$method() failed: $rawSql", __METHOD__);
|
||||||
$errorInfo = $e instanceof \PDOException ? $e->errorInfo : null;
|
$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::endProfile($token, __METHOD__);
|
||||||
Yii::error("Failed to open DB connection ({$this->dsn}): " . $e->getMessage(), __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.';
|
$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;
|
$context = $this->context;
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<li class="<?php if (!$context->isCoreFile($file)) echo 'application'; ?> call-stack-item">
|
<li class="<?php if (!$context->isCoreFile($file)) echo 'application'; ?> call-stack-item">
|
||||||
<div class="element-wrap">
|
<div class="element-wrap">
|
||||||
<div class="element">
|
<div class="element">
|
||||||
|
|||||||
@@ -93,6 +93,35 @@ html,body{
|
|||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
text-shadow: 0 1px 0 #cacaca;
|
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 */
|
||||||
.call-stack{
|
.call-stack{
|
||||||
@@ -131,7 +160,7 @@ html,body{
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
.call-stack ul li .text{
|
.call-stack ul li .text{
|
||||||
color: #bbb;
|
color: #aaa;
|
||||||
}
|
}
|
||||||
.call-stack ul li.application .text{
|
.call-stack ul li.application .text{
|
||||||
color: #505050;
|
color: #505050;
|
||||||
@@ -139,7 +168,7 @@ html,body{
|
|||||||
.call-stack ul li .at{
|
.call-stack ul li .at{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 110px; /* 50px + 60px */
|
right: 110px; /* 50px + 60px */
|
||||||
color: #bbb;
|
color: #aaa;
|
||||||
}
|
}
|
||||||
.call-stack ul li.application .at{
|
.call-stack ul li.application .at{
|
||||||
color: #505050;
|
color: #505050;
|
||||||
@@ -185,7 +214,7 @@ html,body{
|
|||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-family: Consolas, Courier New, monospace;
|
font-family: Consolas, Courier New, monospace;
|
||||||
color: #bbb;
|
color: #aaa;
|
||||||
}
|
}
|
||||||
.call-stack ul li .code pre{
|
.call-stack ul li .code pre{
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -335,6 +364,7 @@ pre .diff .change{
|
|||||||
?></h1>
|
?></h1>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<h2><?php echo $context->htmlEncode($exception->getMessage()); ?></h2>
|
<h2><?php echo $context->htmlEncode($exception->getMessage()); ?></h2>
|
||||||
|
<?php echo $context->renderPreviousExceptions($exception); ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="call-stack">
|
<div class="call-stack">
|
||||||
|
|||||||
20
framework/yii/views/errorHandler/previousException.php
Normal file
20
framework/yii/views/errorHandler/previousException.php
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<div class="previous">
|
||||||
|
<h1><span class="arrow">↵</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 ' – ' . $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>
|
||||||
Reference in New Issue
Block a user