Skip to content

Commit

Permalink
Merge pull request #596 from florianorben/593-display-list-of-prev-ex…
Browse files Browse the repository at this point in the history
…ception-msgs

Display messages from previous exceptions
  • Loading branch information
denis-sokolov committed Oct 20, 2018
2 parents 33e8f29 + 352cba6 commit d52aaee
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 12 deletions.
49 changes: 48 additions & 1 deletion src/Whoops/Exception/Inspector.php
Expand Up @@ -25,6 +25,11 @@ class Inspector
*/
private $previousExceptionInspector;

/**
* @var \Throwable[]
*/
private $previousExceptions;

/**
* @param \Throwable $exception The exception to inspect
*/
Expand Down Expand Up @@ -57,6 +62,28 @@ public function getExceptionMessage()
return $this->extractDocrefUrl($this->exception->getMessage())['message'];
}

/**
* @return string[]
*/
public function getPreviousExceptionMessages()
{
return array_map(function ($prev) {
/** @var \Throwable $prev */
return $this->extractDocrefUrl($prev->getMessage())['message'];
}, $this->getPreviousExceptions());
}

/**
* @return int[]
*/
public function getPreviousExceptionCodes()
{
return array_map(function ($prev) {
/** @var \Throwable $prev */
return $prev->getCode();
}, $this->getPreviousExceptions());
}

/**
* Returns a url to the php-manual related to the underlying error - when available.
*
Expand Down Expand Up @@ -117,6 +144,26 @@ public function getPreviousExceptionInspector()
return $this->previousExceptionInspector;
}


/**
* Returns an array of all previous exceptions for this inspector's exception
* @return \Throwable[]
*/
public function getPreviousExceptions()
{
if ($this->previousExceptions === null) {
$this->previousExceptions = [];

$prev = $this->exception->getPrevious();
while ($prev !== null) {
$this->previousExceptions[] = $prev;
$prev = $prev->getPrevious();
}
}

return $this->previousExceptions;
}

/**
* Returns an iterator for the inspected exception's
* frames.
Expand Down Expand Up @@ -188,7 +235,7 @@ public function getFrames()
*
* If xdebug is installed
*
* @param \Throwable $exception
* @param \Throwable $e
* @return array
*/
protected function getTrace($e)
Expand Down
22 changes: 12 additions & 10 deletions src/Whoops/Handler/PrettyPageHandler.php
Expand Up @@ -205,16 +205,18 @@ public function handle()
"frame_code" => $this->getResource("views/frame_code.html.php"),
"env_details" => $this->getResource("views/env_details.html.php"),

"title" => $this->getPageTitle(),
"name" => explode("\\", $inspector->getExceptionName()),
"message" => $inspector->getExceptionMessage(),
"docref_url" => $inspector->getExceptionDocrefUrl(),
"code" => $code,
"plain_exception" => Formatter::formatExceptionPlain($inspector),
"frames" => $frames,
"has_frames" => !!count($frames),
"handler" => $this,
"handlers" => $this->getRun()->getHandlers(),
"title" => $this->getPageTitle(),
"name" => explode("\\", $inspector->getExceptionName()),
"message" => $inspector->getExceptionMessage(),
"previousMessages" => $inspector->getPreviousExceptionMessages(),
"docref_url" => $inspector->getExceptionDocrefUrl(),
"code" => $code,
"previousCodes" => $inspector->getPreviousExceptionCodes(),
"plain_exception" => Formatter::formatExceptionPlain($inspector),
"frames" => $frames,
"has_frames" => !!count($frames),
"handler" => $this,
"handlers" => $this->getRun()->getHandlers(),

"active_frames_tab" => count($frames) && $frames->offsetGet(0)->isApplication() ? 'application' : 'all',
"has_frames_tabs" => $this->getApplicationPaths(),
Expand Down
21 changes: 20 additions & 1 deletion src/Whoops/Resources/css/whoops.base.css
Expand Up @@ -52,7 +52,7 @@ header {
color: #bebebe;
font-size: 14px;
}
.exc-title-primary {
.exc-title-primary, .exc-title-secondary {
color: #e95353;
}

Expand All @@ -70,6 +70,25 @@ header {
font-weight: 300;
}

.prev-exc-title {
margin: 10px 0;
}

.prev-exc-title + ul {
margin: 0;
padding: 0 0 0 20px;
line-height: 12px;
}

.prev-exc-title + ul li {
font: 12px "Helvetica Neue", helvetica, arial, sans-serif;
}

.prev-exc-title + ul li .prev-exc-code {
display: inline-block;
color: #bebebe;
}

.details-container {
left: 30%;
width: 70%;
Expand Down
19 changes: 19 additions & 0 deletions src/Whoops/Resources/views/header.html.php
Expand Up @@ -15,6 +15,25 @@
<div class="exc-message">
<?php if (!empty($message)): ?>
<span><?php echo $tpl->escape($message) ?></span>


<?php if (count($previousMessages)): ?>
<div class="exc-title prev-exc-title">
<span class="exc-title-secondary">Previous exceptions</span>
</div>

<ul>
<?php foreach ($previousMessages as $i => $previousMessage): ?>
<li>
<?php echo $tpl->escape($previousMessage) ?>
<span class="prev-exc-code">(<?php echo $previousCodes[$i] ?>)</span>
</li>
<?php endforeach; ?>
</ul>
<?php endif ?>



<?php else: ?>
<span class="exc-message-empty-notice">No message</span>
<?php endif ?>
Expand Down
64 changes: 64 additions & 0 deletions tests/Whoops/Exception/InspectorTest.php
Expand Up @@ -119,4 +119,68 @@ public function testNegativeHasPreviousException()

$this->assertFalse($inspector->hasPreviousException());
}

/**
* @covers Whoops\Exception\Inspector::getPreviousExceptions
*/
public function testGetPreviousExceptionsReturnsListOfExceptions()
{
$exception1 = $this->getException('My first exception');
$exception2 = $this->getException('My second exception', 0, $exception1);
$exception3 = $this->getException('And the third one', 0, $exception2);

$inspector = $this->getInspectorInstance($exception3);

$previousExceptions = $inspector->getPreviousExceptions();
$this->assertCount(2, $previousExceptions);
$this->assertEquals($exception2, $previousExceptions[0]);
$this->assertEquals($exception1, $previousExceptions[1]);
}

/**
* @covers Whoops\Exception\Inspector::getPreviousExceptions
*/
public function testGetPreviousExceptionsReturnsEmptyListIfThereAreNoPreviousExceptions()
{
$exception = $this->getException('My exception');
$inspector = $this->getInspectorInstance($exception);

$previousExceptions = $inspector->getPreviousExceptions();
$this->assertCount(0, $previousExceptions);
}

/**
* @covers Whoops\Exception\Inspector::getPreviousExceptionMessages
*/
public function testGetPreviousExceptionMessages()
{
$exception1 = $this->getException('My first exception');
$exception2 = $this->getException('My second exception', 0, $exception1);
$exception3 = $this->getException('And the third one', 0, $exception2);

$inspector = $this->getInspectorInstance($exception3);

$previousExceptions = $inspector->getPreviousExceptionMessages();

$this->assertEquals($exception2->getMessage(), $previousExceptions[0]);
$this->assertEquals($exception1->getMessage(), $previousExceptions[1]);
}


/**
* @covers Whoops\Exception\Inspector::getPreviousExceptionCodes
*/
public function testGetPreviousExceptionCodes()
{
$exception1 = $this->getException('My first exception', 99);
$exception2 = $this->getException('My second exception', 20, $exception1);
$exception3 = $this->getException('And the third one', 10, $exception2);

$inspector = $this->getInspectorInstance($exception3);

$previousExceptions = $inspector->getPreviousExceptionCodes();

$this->assertEquals($exception2->getCode(), $previousExceptions[0]);
$this->assertEquals($exception1->getCode(), $previousExceptions[1]);
}
}

0 comments on commit d52aaee

Please sign in to comment.