Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. StackTraceFormatter.php

class StackTraceFormatter

@psalm-type Frame = array{ function: string, class: ?class-string, file: ?string, line: ?int, } @psalm-type Frames = non-empty-list<Frame>

Hierarchy

  • class \OpenTelemetry\SDK\Common\Exception\StackTraceFormatter

Expanded class hierarchy of StackTraceFormatter

1 file declares its use of StackTraceFormatter
Span.php in vendor/open-telemetry/sdk/Trace/Span.php

File

vendor/open-telemetry/sdk/Common/Exception/StackTraceFormatter.php, line 23

Namespace

OpenTelemetry\SDK\Common\Exception
View source
final class StackTraceFormatter {
    private function __construct() {
    }
    
    /**
     * Formats an exception in a java-like format.
     *
     * @param Throwable $e exception to format
     * @return string formatted exception
     *
     * @see https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Throwable.html#printStackTrace()
     */
    public static function format(Throwable $e) : string {
        $s = '';
        $seen = [];
        
        /** @psalm-var Frames|null $enclosing */
        $enclosing = null;
        do {
            if ($enclosing) {
                self::writeNewline($s);
                $s .= 'Caused by: ';
            }
            if (isset($seen[spl_object_id($e)])) {
                $s .= '[CIRCULAR REFERENCE: ';
                self::writeInlineHeader($s, $e);
                $s .= ']';
                break;
            }
            $seen[spl_object_id($e)] = $e;
            $frames = self::frames($e);
            self::writeInlineHeader($s, $e);
            self::writeFrames($s, $frames, $enclosing);
            $enclosing = $frames;
        } while ($e = $e->getPrevious());
        return $s;
    }
    
    /**
     * @phan-suppress-next-line PhanTypeMismatchDeclaredParam
     * @psalm-param Frames $frames
     * @phan-suppress-next-line PhanTypeMismatchDeclaredParam
     * @psalm-param Frames|null $enclosing
     */
    private static function writeFrames(string &$s, array $frames, ?array $enclosing) : void {
        $n = count($frames);
        if ($enclosing) {
            for ($m = count($enclosing); $n && $m && $frames[$n - 1] === $enclosing[$m - 1]; $n--, $m--) {
            }
        }
        for ($i = 0; $i < $n; $i++) {
            $frame = $frames[$i];
            self::writeNewline($s, 1);
            $s .= 'at ';
            if ($frame['class'] !== null) {
                $s .= self::formatName($frame['class']);
                $s .= '.';
            }
            $s .= self::formatName($frame['function']);
            $s .= '(';
            if ($frame['file'] !== null) {
                $s .= basename($frame['file']);
                if ($frame['line']) {
                    $s .= ':';
                    $s .= $frame['line'];
                }
            }
            else {
                $s .= 'Unknown Source';
            }
            $s .= ')';
        }
        if ($n !== count($frames)) {
            self::writeNewline($s, 1);
            $s .= sprintf('... %d more', count($frames) - $n);
        }
    }
    private static function writeInlineHeader(string &$s, Throwable $e) : void {
        $s .= self::formatName($e::class);
        if ($e->getMessage() !== '') {
            $s .= ': ';
            $s .= $e->getMessage();
        }
    }
    private static function writeNewline(string &$s, int $indent = 0) : void {
        $s .= "\n";
        $s .= str_repeat("\t", $indent);
    }
    
    /**
     * @psalm-return Frames
     * @psalm-suppress PossiblyUndefinedArrayOffset
     * @psalm-suppress InvalidArrayOffset
     */
    private static function frames(Throwable $e) : array {
        $frames = [];
        $trace = $e->getTrace();
        $traceCount = count($trace);
        for ($i = 0; $i < $traceCount + 1; $i++) {
            $frames[] = [
                'function' => $trace[$i]['function'] ?? '{main}',
                'class' => $trace[$i]['class'] ?? null,
                'file' => $trace[$i - 1]['file'] ?? null,
                'line' => $trace[$i - 1]['line'] ?? null,
            ];
        }
        $frames[0]['file'] = $e->getFile();
        $frames[0]['line'] = $e->getLine();
        
        /** @psalm-var Frames $frames */
        return $frames;
    }
    private static function formatName(string $name) : string {
        return strtr($name, [
            '\\' => '.',
        ]);
    }

}

Members

Title Sort descending Modifiers Object type Summary
StackTraceFormatter::format public static function Formats an exception in a java-like format.
StackTraceFormatter::formatName private static function
StackTraceFormatter::frames private static function @psalm-return Frames
@psalm-suppress PossiblyUndefinedArrayOffset
@psalm-suppress InvalidArrayOffset
StackTraceFormatter::writeFrames private static function @phan-suppress-next-line PhanTypeMismatchDeclaredParam
@psalm-param Frames $frames
@phan-suppress-next-line PhanTypeMismatchDeclaredParam
@psalm-param Frames|null $enclosing
StackTraceFormatter::writeInlineHeader private static function
StackTraceFormatter::writeNewline private static function
StackTraceFormatter::__construct private function
RSS feed
Powered by Drupal