$file, "line" => $line, "class" => $class, "object" => null, "type" => $type, "function" => $function, "args" => [], ]; } return $frames; } function __construct(Throwable $exception) { $this->class = get_class($exception); $this->message = $exception->getMessage(); $this->code = $exception->getCode(); $this->file = $exception->getFile(); $this->line = $exception->getLine(); $this->trace = self::extract_trace($exception->getTrace()); $previous = $exception->getPrevious(); if ($previous !== null) $this->previous = new static($previous); if ($exception instanceof UserException) { $this->userMessage = $exception->getUserMessage(); $this->techMessage = $exception->getTechMessage(); } else { $this->userMessage = null; $this->techMessage = null; } } protected string $class; function getClass(): string { return $this->class; } protected string $message; function getMessage(): string { return $this->message; } /** @var mixed */ protected $code; function getCode() { return $this->code; } protected string $file; function getFile(): string { return $this->file; } protected int $line; function getLine(): int { return $this->line; } protected array $trace; function getTrace(): array { return $this->trace; } function getTraceAsString(): string { $lines = []; foreach ($this->trace as $index => $frame) { $lines[] = "#$index $frame[file]($frame[line]): $frame[class]$frame[type]$frame[function]()"; } $index++; $lines[] = "#$index {main}"; return implode("\n", $lines); } protected ?ExceptionShadow $previous; function getPrevious(): ?ExceptionShadow { return $this->previous; } protected ?array $userMessage; function getUserMessage(): ?array { return $this->userMessage; } protected ?array $techMessage; function getTechMessage(): ?array { return $this->techMessage; } }