Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## 5.0.0 under development

- Enh #104: Render exception class PHPDoc description with safe markdown links in HTML debug output (@dbuhonov)
- Enh #104, #168: Render exception class PHPDoc description with safe markdown links in HTML debug output (@dbuhonov, @vjik)
- Chg #162: Replace deprecated `ThrowableResponseFactory` class usage to new one, and remove it (@vjik)
- Enh #163: Explicitly import classes, functions, and constants in "use" section (@mspirkov)
- Bug #164: Fix missing items in stack trace HTML output when handling a PHP error (@vjik)
Expand Down
24 changes: 8 additions & 16 deletions src/Renderer/HtmlRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -212,26 +212,23 @@ public function render(Throwable $t, ?ServerRequestInterface $request = null): E

public function renderVerbose(Throwable $t, ?ServerRequestInterface $request = null): ErrorData
{
$solution = null;
$exceptionDescription = null;
$displayThrowable = $t;

if ($t instanceof CompositeException) {
$displayThrowable = $t->getFirstException();
}

if ($displayThrowable instanceof FriendlyExceptionInterface) {
$solution = $displayThrowable->getSolution();
} else {
$exceptionDescription = $this->getThrowableDescription($displayThrowable);
$exceptionDescription = $displayThrowable instanceof FriendlyExceptionInterface
? $displayThrowable->getSolution()
: $this->getThrowableDescription($displayThrowable);
if ($exceptionDescription !== null) {
$exceptionDescription = $this->parseMarkdown($exceptionDescription);
}

return new ErrorData(
$this->renderTemplate($this->verboseTemplate, [
'request' => $request,
'throwable' => $t,
'displayThrowable' => $displayThrowable,
'solution' => $solution,
'exceptionClass' => $displayThrowable::class,
'exceptionMessage' => $displayThrowable->getMessage(),
'exceptionDescription' => $exceptionDescription,
Expand Down Expand Up @@ -576,11 +573,8 @@ public function removeAnonymous(string $value): string
* suitable for direct inclusion in the error template.
* Inline {@see ...}/{@link ...} annotations are rendered as markdown links.
*
* The returned value is an HTML snippet (for example, containing <p>, <a>,
* <code> elements) and is intended to be inserted into the template as-is,
* without additional HTML-escaping.
*
* @return string|null HTML fragment describing the throwable, or null if no description is available.
* @return string|null Markdown string with inline HTML (`<code>` elements) describing the throwable, or `null` if
* no description is available.
*/
private function getThrowableDescription(Throwable $throwable): ?string
{
Expand Down Expand Up @@ -668,9 +662,7 @@ static function (array $matches): string {
$normalized[] = $imageMarker . $label . ' (<code>' . $this->htmlEncode($target) . '</code>)';
}

$normalized = trim(implode('', $normalized));

return $this->parseMarkdown($normalized);
return trim(implode('', $normalized));
}

/**
Expand Down
72 changes: 36 additions & 36 deletions templates/development.css
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ header {
--previous-arrow-color: #e51717;
}

header .solution {
header .exception-description {
--text-color: var(--page-text-color);
--link-color: #00617b;
--link-hover-color: #1191b3;
Expand Down Expand Up @@ -257,115 +257,115 @@ header .exception-message {
color: var(--exception-message-text-color);
}

header .solution {
header .exception-description {
margin-top: 24px;
font-size: 16px;
line-height: 22px;
color: var(--text-color);
}

header .solution h1 {
header .exception-description h1 {
margin-top: 24px;
font-size: 26px;
line-height: 32px;
font-weight: bold;
}

header .solution h2 {
header .exception-description h2 {
margin-top: 24px;
font-size: 22px;
line-height: 28px;
font-weight: bold;
}

header .solution h3 {
header .exception-description h3 {
margin-top: 24px;
font-size: 20px;
line-height: 26px;
font-weight: bold;
}

header .solution h4 {
header .exception-description h4 {
margin-top: 24px;
font-size: 18px;
line-height: 24px;
font-weight: bold;
}

header .solution h5 {
header .exception-description h5 {
margin-top: 24px;
font-size: 16px;
line-height: 22px;
font-weight: bold;
}

header .solution h6 {
header .exception-description h6 {
margin-top: 24px;
font-size: 14px;
line-height: 20px;
font-weight: bold;
}

header .solution p {
header .exception-description p {
margin-top: 16px;
}

header .solution a {
header .exception-description a {
color: var(--link-color);
text-decoration: underline;
}
header .solution a:hover {
header .exception-description a:hover {
color: var(--link-hover-color);
}

header .solution h1:first-child,
header .solution h2:first-child,
header .solution h3:first-child,
header .solution h4:first-child,
header .solution h5:first-child,
header .solution h6:first-child,
header .solution p:first-child {
header .exception-description h1:first-child,
header .exception-description h2:first-child,
header .exception-description h3:first-child,
header .exception-description h4:first-child,
header .exception-description h5:first-child,
header .exception-description h6:first-child,
header .exception-description p:first-child {
margin-top: 0;
}

header .solution blockquote {
header .exception-description blockquote {
margin: 18px 0 18px 4px;
padding: 3px 0 2px 16px;
border-left: 4px solid var(--blockquote-border-color);
color: var(--blockquote-text-color);
}

header .solution ul,
header .solution ol {
header .exception-description ul,
header .exception-description ol {
padding: 0;
margin: 16px 0 0 32px;
}
header .solution li ul,
header .solution li ol {
header .exception-description li ul,
header .exception-description li ol {
margin: 0 0 0 24px;
}

header .solution li {
header .exception-description li {
margin: 8px 0 0 0;
}

header .solution ul {
header .exception-description ul {
list-style: outside;
}

header .solution pre,
header .solution code {
header .exception-description pre,
header .exception-description code {
font-family: monospace;
}

header .solution code {
header .exception-description code {
padding: 2px 6px;
font-size: 90%;
background-color: var(--code-bg-color);
border-radius: 6px;
}

header .solution pre {
header .exception-description pre {
margin: 24px 0;
width: 100%;
box-sizing: border-box;
Expand All @@ -374,23 +374,23 @@ header .solution pre {
border-radius: 8px;
background: var(--pre-bg-color);
}
header .solution pre code {
header .exception-description pre code {
font-size: 100%;
padding: 0;
width: max-content;
}

header .solution table {
header .exception-description table {
margin: 16px 0 0 0;
border-collapse: collapse;
}
header .solution td,
header .solution th {
header .exception-description td,
header .exception-description th {
padding: 6px 12px;
border: 1px solid var(--table-border-color);
}

header .solution HR {
header .exception-description HR {
margin: 24px 0;
border: 1px solid var(--separator-color);
border-width: 1px 0 0 0;
Expand Down Expand Up @@ -836,7 +836,7 @@ main {
--exception-message-text-color: rgba(255, 255, 255, 0.8);
}

.dark-theme header .solution {
.dark-theme header .exception-description {
--text-color: rgba(255, 255, 255, 0.8);
--link-color: #03a9f4;
--link-hover-color: #39b9f3;
Expand Down Expand Up @@ -918,7 +918,7 @@ main {
--exception-message-text-color: rgba(255, 255, 255, 0.8);
}

body:not(.light-theme) header .solution {
body:not(.light-theme) header .exception-description {
--text-color: rgba(255, 255, 255, 0.8);
--link-color: #03a9f4;
--link-hover-color: #39b9f3;
Expand Down
9 changes: 2 additions & 7 deletions templates/development.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
* @var ServerRequestInterface|null $request
* @var Throwable $throwable
* @var Throwable $displayThrowable
* @var string|null $solution
* @var string $exceptionClass
* @var string $exceptionMessage
* @var string|null $exceptionDescription
Expand Down Expand Up @@ -90,11 +89,7 @@
</div>

<?php if ($exceptionDescription !== null): ?>
<div class="exception-description solution"><?= $exceptionDescription ?></div>
<?php endif ?>

<?php if ($solution !== null): ?>
<div class="solution"><?= $this->parseMarkdown($solution) ?></div>
<div class="exception-description"><?= $exceptionDescription ?></div>
<?php endif ?>

<?= $this->renderPreviousExceptions($throwable) ?>
Expand Down Expand Up @@ -206,7 +201,7 @@ class="copy-clipboard"
const DARK_THEME = 'dark-theme';

window.onload = function() {
const codeBlocks = document.querySelectorAll('.solution pre code,.codeBlock');
const codeBlocks = document.querySelectorAll('.exception-description pre code,.codeBlock');
const callStackItems = document.getElementsByClassName('call-stack-item');

// If there are grouped vendor package files
Expand Down
Loading
Loading