1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Analyser;
4:
5: use JsonSerializable;
6: use ReturnTypeWillChange;
7: use Throwable;
8: use function array_map;
9: use function array_unshift;
10:
11: /**
12: * @api
13: * @final
14: * @phpstan-type Trace = list<array{file: string|null, line: int|null}>
15: */
16: class InternalError implements JsonSerializable
17: {
18:
19: public const STACK_TRACE_METADATA_KEY = 'stackTrace';
20:
21: public const STACK_TRACE_AS_STRING_METADATA_KEY = 'stackTraceAsString';
22:
23: /**
24: * @param Trace $trace
25: */
26: public function __construct(
27: private string $message,
28: private string $contextDescription,
29: private array $trace,
30: private ?string $traceAsString,
31: private bool $shouldReportBug,
32: )
33: {
34: }
35:
36: /**
37: * @return Trace
38: */
39: public static function prepareTrace(Throwable $exception): array
40: {
41: $trace = array_map(static fn (array $trace) => [
42: 'file' => $trace['file'] ?? null,
43: 'line' => $trace['line'] ?? null,
44: ], $exception->getTrace());
45:
46: array_unshift($trace, [
47: 'file' => $exception->getFile(),
48: 'line' => $exception->getLine(),
49: ]);
50:
51: return $trace;
52: }
53:
54: public function getMessage(): string
55: {
56: return $this->message;
57: }
58:
59: public function getContextDescription(): string
60: {
61: return $this->contextDescription;
62: }
63:
64: /**
65: * @return Trace
66: */
67: public function getTrace(): array
68: {
69: return $this->trace;
70: }
71:
72: public function getTraceAsString(): ?string
73: {
74: return $this->traceAsString;
75: }
76:
77: public function shouldReportBug(): bool
78: {
79: return $this->shouldReportBug;
80: }
81:
82: /**
83: * @param mixed[] $json
84: */
85: public static function decode(array $json): self
86: {
87: return new self($json['message'], $json['contextDescription'], $json['trace'], $json['traceAsString'], $json['shouldReportBug']);
88: }
89:
90: /**
91: * @return mixed
92: */
93: #[ReturnTypeWillChange]
94: public function jsonSerialize()
95: {
96: return [
97: 'message' => $this->message,
98: 'contextDescription' => $this->contextDescription,
99: 'trace' => $this->trace,
100: 'traceAsString' => $this->traceAsString,
101: 'shouldReportBug' => $this->shouldReportBug,
102: ];
103: }
104:
105: }
106: