0 follower

Final Class Yiisoft\ErrorHandler\Renderer\HtmlRenderer

InheritanceYiisoft\ErrorHandler\Renderer\HtmlRenderer
ImplementsYiisoft\ErrorHandler\ThrowableRendererInterface

Formats throwable into HTML string.

Psalm Types

Name Value
TraceLinkClosure callable

Public Properties

Hide inherited properties

Property Type Description Defined By
$traceHeaderLine string|null The trace header line with placeholders to be substituted. Yiisoft\ErrorHandler\Renderer\HtmlRenderer
$traceLinkGenerator Closure Yiisoft\ErrorHandler\Renderer\HtmlRenderer

Constants

Hide inherited constants

Constant Value Description Defined By
CONTENT_TYPE 'text/html' Yiisoft\ErrorHandler\Renderer\HtmlRenderer
DEFAULT_ERROR_MESSAGE 'An internal server error occurred.' Yiisoft\ErrorHandler\ThrowableRendererInterface

Property Details

Hide inherited properties

$traceHeaderLine public property

The trace header line with placeholders to be substituted. Defaults to null.

The placeholders are {file}, {line} and {icon}. A typical use case is the creation of IDE-specific links, since when you click on a trace header link, it opens directly in the IDE. You can also insert custom content.

Example IDE link:

<a href="ide://open?file={file}&line={line}">{icon}</a>
$traceLinkGenerator public property

Method Details

Hide inherited methods

__construct() public method

public mixed __construct ( array $settings = [], string|null $template null, string|null $verboseTemplate null, integer|null $maxSourceLines null, integer|null $maxTraceLines null, string|null $traceHeaderLine null, Closure|string|null $traceLink null )
$settings array

(deprecated) Settings can have the following keys:

  • template: string, full path of the template file for rendering exceptions without call stack information.
  • verboseTemplate: string, full path of the template file for rendering exceptions with call stack information.
  • maxSourceLines: int, maximum number of source code lines to be displayed. Defaults to 19.
  • maxTraceLines: int, maximum number of trace source code lines to be displayed. Defaults to 13.
  • traceHeaderLine: string, trace header line with placeholders to be substituted. Defaults to null.
$template string|null

The full path of the template file for rendering exceptions without call stack information.

$verboseTemplate string|null

The full path of the template file for rendering exceptions with call stack information.

$maxSourceLines integer|null

The maximum number of source code lines to be displayed. Defaults to 19.

$maxTraceLines integer|null

The maximum number of trace source code lines to be displayed. Defaults to 13.

$traceHeaderLine string|null

Deprecated, use {@see \Yiisoft\ErrorHandler\Renderer\traceLink} instead. The trace header line with placeholders to be substituted. Defaults to null.

$traceLink Closure|string|null

The trace link. It can be a string with placeholders file and line to be substituted or a closure that accepts file and line parameters and returns a string or null. Examples:

  • string "ide://open?file={file}&line={line}";
  • closure:
    static function (string $file, ?int $line): string {
        return strtr(
            'phpstorm://open?file={file}&line={line}',
            ['{file}' => $file, '{line}' => (string) $line],
        );
    }
    

                public function __construct(
    array $settings = [],
    ?string $template = null,
    ?string $verboseTemplate = null,
    ?int $maxSourceLines = null,
    ?int $maxTraceLines = null,
    ?string $traceHeaderLine = null,
    string|Closure|null $traceLink = null,
) {
    $this->markdownParser = new GithubMarkdown();
    $this->markdownParser->html5 = true;
    $this->defaultTemplatePath = dirname(__DIR__, 2) . '/templates';
    $this->template = $template
        ?? $settings['template']
        ?? $this->defaultTemplatePath . '/production.php';
    $this->verboseTemplate = $verboseTemplate
        ?? $settings['verboseTemplate']
        ?? $this->defaultTemplatePath . '/development.php';
    $this->maxSourceLines = $maxSourceLines
        ?? $settings['maxSourceLines']
        ?? 19;
    $this->maxTraceLines = $maxTraceLines
        ?? $settings['maxTraceLines']
        ?? 13;
    $this->traceHeaderLine = $traceHeaderLine
        ?? $settings['traceHeaderLine']
        ?? null;
    $this->traceLinkGenerator = $this->createTraceLinkGenerator($traceLink);
}

            
argumentsToString() public method

Converts arguments array to its string representation.

public string argumentsToString ( array $args, boolean $truncate true )
$args array

Arguments array to be converted

$truncate boolean
return string

The string representation of the arguments array.

                public function argumentsToString(array $args, bool $truncate = true): string
{
    $count = 0;
    $isAssoc = $args !== array_values($args);
    /**
     * @var mixed $value
     */
    foreach ($args as $key => $value) {
        $count++;
        if ($truncate && $count >= 5) {
            if ($count > 5) {
                unset($args[$key]);
            } else {
                $args[$key] = '...';
            }
            continue;
        }
        if (is_object($value)) {
            $args[$key] = '<span class="title">' . $this->htmlEncode($this->removeAnonymous($value::class) . '#' . spl_object_id($value)) . '</span>';
        } elseif (is_bool($value)) {
            $args[$key] = '<span class="keyword">' . ($value ? 'true' : 'false') . '</span>';
        } elseif (is_string($value)) {
            $fullValue = $this->htmlEncode($value);
            if ($truncate && mb_strlen($value, 'UTF-8') > 32) {
                $displayValue = $this->htmlEncode(mb_substr($value, 0, 32, 'UTF-8')) . '...';
                $args[$key] = "<span class=\"string\" title=\"$fullValue\">'$displayValue'</span>";
            } else {
                $args[$key] = "<span class=\"string\">'$fullValue'</span>";
            }
        } elseif (is_array($value)) {
            unset($args[$key]);
            $args[$key] = '[' . $this->argumentsToString($value, $truncate) . ']';
        } elseif ($value === null) {
            $args[$key] = '<span class="keyword">null</span>';
        } elseif (is_resource($value)) {
            $args[$key] = '<span class="keyword">resource</span>';
        } else {
            $args[$key] = '<span class="number">' . (string) $value . '</span>';
        }
        if (is_string($key)) {
            $args[$key] = '<span class="string">\'' . $this->htmlEncode($key) . "'</span> => $args[$key]";
        } elseif ($isAssoc) {
            $args[$key] = "<span class=\"number\">$key</span> => $args[$key]";
        }
    }
    /** @var string[] $args */
    ksort($args);
    return implode(', ', $args);
}

            
createServerInformationLink() public method

Creates string containing HTML link which refers to the home page of determined web-server software and its full name.

public string createServerInformationLink ( \Psr\Http\Message\ServerRequestInterface $request )
$request \Psr\Http\Message\ServerRequestInterface
return string

The server software information hyperlink.

getThrowableName() public method

Returns the name of the throwable instance.

public string getThrowableName ( Throwable $throwable )
$throwable Throwable
return string

The name of the throwable instance.

                public function getThrowableName(Throwable $throwable): string
{
    $name = $throwable::class;
    if ($throwable instanceof FriendlyExceptionInterface) {
        $name = $throwable->getName() . ' (' . $name . ')';
    }
    return $name;
}

            
htmlEncode() public method

Encodes special characters into HTML entities for use as a content.

public string htmlEncode ( string $content )
$content string

The content to be encoded.

return string

Encoded content.

                public function htmlEncode(string $content): string
{
    return htmlspecialchars($content, ENT_QUOTES, 'UTF-8');
}

            
parseMarkdown() public method

public string parseMarkdown ( string $content )
$content string

                public function parseMarkdown(string $content): string
{
    $html = $this->markdownParser->parse($content);
    /**
     * @psalm-suppress InvalidArgument
     *
     * @link https://github.com/vimeo/psalm/issues/4317
     */
    return strip_tags($html, [
        'h1',
        'h2',
        'h3',
        'h4',
        'h5',
        'h6',
        'hr',
        'pre',
        'code',
        'blockquote',
        'table',
        'tr',
        'td',
        'th',
        'thead',
        'tbody',
        'strong',
        'em',
        'b',
        'i',
        'u',
        's',
        'span',
        'a',
        'p',
        'br',
        'nobr',
        'ul',
        'ol',
        'li',
        'img',
    ]);
}

            
removeAnonymous() public method

public string removeAnonymous ( string $value )
$value string

                public function removeAnonymous(string $value): string
{
    $anonymousPosition = strpos($value, '@anonymous');
    return $anonymousPosition !== false ? substr($value, 0, $anonymousPosition) : $value;
}

            
render() public method

public Yiisoft\ErrorHandler\ErrorData render ( Throwable $t, \Psr\Http\Message\ServerRequestInterface|null $request null )
$t Throwable
$request \Psr\Http\Message\ServerRequestInterface|null

                public function render(Throwable $t, ?ServerRequestInterface $request = null): ErrorData
{
    return new ErrorData(
        $this->renderTemplate($this->template, [
            'request' => $request,
            'throwable' => $t,
        ]),
        [Header::CONTENT_TYPE => self::CONTENT_TYPE],
    );
}

            
renderCallStack() public method

Renders call stack.

public string renderCallStack ( Throwable $t, array $trace = [] )
$t Throwable

The exception to get call stack from.

$trace array
return string

HTML content of the rendered call stack.

throws Throwable

                public function renderCallStack(Throwable $t, array $trace = []): string
{
    $application = $vendor = [];
    $application[1] = $this->renderCallStackItem(
        $t->getFile(),
        $t->getLine(),
        null,
        null,
        [],
        1,
        false,
        [],
    );
    $index = 1;
    if ($t instanceof ErrorException) {
        $index = 0;
    }
    foreach ($trace as $traceItem) {
        $file = !empty($traceItem['file']) ? $traceItem['file'] : null;
        $line = !empty($traceItem['line']) ? $traceItem['line'] : null;
        $class = !empty($traceItem['class']) ? $traceItem['class'] : null;
        $args = !empty($traceItem['args']) ? $traceItem['args'] : [];
        $parameters = [];
        $function = null;
        if (!empty($traceItem['function']) && $traceItem['function'] !== 'unknown') {
            $function = $traceItem['function'];
            if (!str_contains($function, '{closure}')) {
                try {
                    if ($class !== null && class_exists($class)) {
                        $parameters = (new \ReflectionMethod($class, $function))->getParameters();
                    } elseif (function_exists($function)) {
                        $parameters = (new \ReflectionFunction($function))->getParameters();
                    }
                } catch (\ReflectionException) {
                    // pass
                }
            }
        }
        $index++;
        if ($this->isVendorFile($file)) {
            $vendor[$index] = $this->renderCallStackItem(
                $file,
                $line,
                $class,
                $function,
                $args,
                $index,
                true,
                $parameters,
            );
        } else {
            $application[$index] = $this->renderCallStackItem(
                $file,
                $line,
                $class,
                $function,
                $args,
                $index,
                false,
                $parameters,
            );
        }
    }
    return $this->renderTemplate($this->defaultTemplatePath . '/_call-stack-items.php', [
        'applicationItems' => $application,
        'vendorItemGroups' => $this->groupVendorCallStackItems($vendor),
    ]);
}

            
renderCurl() public method

Renders the information about curl request.

public string renderCurl ( \Psr\Http\Message\ServerRequestInterface $request )
$request \Psr\Http\Message\ServerRequestInterface
return string

The rendering result.

                public function renderCurl(ServerRequestInterface $request): string
{
    try {
        $output = (new Command())
            ->setRequest($request)
            ->build();
    } catch (Throwable $e) {
        return 'Error generating curl command: ' . $e->getMessage();
    }
    return $output;
}

            
renderPreviousExceptions() public method

Renders the previous exception stack for a given Exception.

public string renderPreviousExceptions ( Throwable $t )
$t Throwable

The exception whose precursors should be rendered.

return string

HTML content of the rendered previous exceptions. Empty string if there are none.

throws Throwable

                public function renderPreviousExceptions(Throwable $t): string
{
    $templatePath = $this->defaultTemplatePath . '/_previous-exception.php';
    if ($t instanceof CompositeException) {
        $result = [];
        foreach ($t->getPreviousExceptions() as $exception) {
            $result[] = $this->renderTemplate($templatePath, ['throwable' => $exception]);
        }
        return implode('', $result);
    }
    if ($t->getPrevious() !== null) {
        return $this->renderTemplate($templatePath, ['throwable' => $t->getPrevious()]);
    }
    return '';
}

            
renderRequest() public method

Renders the information about request.

public string renderRequest ( \Psr\Http\Message\ServerRequestInterface $request )
$request \Psr\Http\Message\ServerRequestInterface
return string

The rendering result.

                public function renderRequest(ServerRequestInterface $request): string
{
    $output = $request->getMethod() . ' ' . $request->getUri() . "\n";
    $headers = $request->getHeaders();
    unset($headers['Host']);
    ksort($headers);
    foreach ($headers as $name => $values) {
        foreach ($values as $value) {
            $output .= "$name: $value\n";
        }
    }
    $body = (string)$request->getBody();
    if (!empty($body)) {
        $output .= "\n" . $body . "\n\n";
    }
    return $output;
}

            
renderVerbose() public method

public Yiisoft\ErrorHandler\ErrorData renderVerbose ( Throwable $t, \Psr\Http\Message\ServerRequestInterface|null $request null )
$t Throwable
$request \Psr\Http\Message\ServerRequestInterface|null

                public function renderVerbose(Throwable $t, ?ServerRequestInterface $request = null): ErrorData
{
    return new ErrorData(
        $this->renderTemplate($this->verboseTemplate, [
            'request' => $request,
            'throwable' => $t,
        ]),
        [Header::CONTENT_TYPE => self::CONTENT_TYPE],
    );
}