$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); } /** @var string */ protected $class; function getClass(): string { return $this->class; } /** @var string */ protected $message; function getMessage(): string { return $this->message; } /** @var mixed */ protected $code; function getCode() { return $this->code; } /** @var string */ protected $file; function getFile(): string { return $this->file; } /** @var int */ protected $line; function getLine(): int { return $this->line; } /** @var array */ protected $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); } /** @var ExceptionShadow */ protected $previous; function getPrevious(): ?ExceptionShadow { return $this->previous; } }