Completed
Push — main ( bdd72f...bbe282 )
by Niels
15s queued 12s
created

ProblemException::withTypeUri()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 6
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the OpenapiBundle package.
7
 *
8
 * (c) Niels Nijens <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Nijens\OpenapiBundle\ExceptionHandling\Exception;
15
16
use Exception;
17
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
18
use Throwable;
19
20
/**
21
 * Default implementation for an RFC 7807 problem JSON object response.
22
 *
23
 * @author Niels Nijens <[email protected]>
24
 */
25
class ProblemException extends Exception implements ProblemExceptionInterface
26
{
27
    private const DEFAULT_TYPE_URI = 'about:blank';
28
29
    private const DEFAULT_TITLE = 'An error occurred.';
30
31
    /**
32
     * @var string
33
     */
34
    private $typeUri;
35
36
    /**
37
     * @var string
38
     */
39
    private $title;
40
41
    /**
42
     * @var string|null
43
     */
44
    private $instanceUri;
45
46
    /**
47
     * @var int
48
     */
49
    private $statusCode;
50
51
    /**
52
     * @var array<string, string>
53
     */
54
    private $headers;
55
56
    public function __construct(
57
        string $typeUri,
58
        string $title,
59
        int $statusCode,
60
        string $message = '',
61
        Throwable $previous = null,
62
        ?string $instanceUri = null,
63
        array $headers = []
64
    ) {
65
        parent::__construct($message, 0, $previous);
66
67
        $this->typeUri = $typeUri;
68
        $this->title = $title;
69
        $this->instanceUri = $instanceUri;
70
        $this->statusCode = $statusCode;
71
        $this->headers = $headers;
72
    }
73
74
    public function getTypeUri(): string
75
    {
76
        return $this->typeUri;
77
    }
78
79
    public function getTitle(): string
80
    {
81
        return $this->title;
82
    }
83
84
    public function getDetail(): ?string
85
    {
86
        return $this->getMessage();
87
    }
88
89
    public function getInstanceUri(): ?string
90
    {
91
        return $this->instanceUri;
92
    }
93
94
    public function getStatusCode(): int
95
    {
96
        return $this->statusCode;
97
    }
98
99
    public function getHeaders(): array
100
    {
101
        return $this->headers;
102
    }
103
104
    public function withTypeUri(string $typeUri): ProblemExceptionInterface
105
    {
106
        $exception = $this->clone();
107
        $exception->typeUri = $typeUri;
108
109
        return $exception;
110
    }
111
112
    public function withTitle(string $title): ProblemExceptionInterface
113
    {
114
        $exception = $this->clone();
115
        $exception->title = $title;
116
117
        return $exception;
118
    }
119
120
    public function withInstanceUri(string $instanceUri): ProblemExceptionInterface
121
    {
122
        $exception = $this->clone();
123
        $exception->instanceUri = $instanceUri;
124
125
        return $exception;
126
    }
127
128
    public function withStatusCode(int $statusCode): ProblemExceptionInterface
129
    {
130
        $exception = $this->clone();
131
        $exception->statusCode = $statusCode;
132
133
        return $exception;
134
    }
135
136
    public function withHeaders(array $headers): ProblemExceptionInterface
137
    {
138
        $exception = $this->clone();
139
        $exception->headers = $headers;
140
141
        return $exception;
142
    }
143
144
    public function jsonSerialize(): array
145
    {
146
        return [
147
            'type' => $this->getTypeUri(),
148
            'title' => $this->getTitle(),
149
            'status' => $this->getStatusCode(),
150
            'detail' => $this->getDetail(),
151
            'instance' => $this->getInstanceUri(),
152
        ];
153
    }
154
155
    public static function fromHttpException(
156
        HttpExceptionInterface $exception,
157
        ?int $statusCode = null,
158
        string $typeUri = self::DEFAULT_TYPE_URI,
159
        string $title = self::DEFAULT_TITLE,
160
        string $instanceUri = null
161
    ): self {
162
        if ($statusCode === null) {
163
            $statusCode = $exception->getStatusCode();
164
        }
165
166
        return new static(
167
            $typeUri,
168
            $title,
169
            $statusCode,
170
            $exception->getMessage(),
171
            $exception,
172
            $instanceUri,
173
            $exception->getHeaders()
174
        );
175
    }
176
177
    public static function fromThrowable(
178
        Throwable $throwable,
179
        int $statusCode = 500,
180
        string $typeUri = self::DEFAULT_TYPE_URI,
181
        string $title = self::DEFAULT_TITLE,
182
        string $instanceUri = null
183
    ): self {
184
        return new static($typeUri, $title, $statusCode, $throwable->getMessage(), $throwable, $instanceUri);
185
    }
186
187
    /**
188
     * @return self
189
     */
190
    protected function clone()
191
    {
192
        return new static(
193
            $this->getTypeUri(),
194
            $this->getTitle(),
195
            $this->getStatusCode(),
196
            $this->getMessage(),
197
            $this->getPrevious(),
198
            $this->getInstanceUri(),
199
            $this->getHeaders()
200
        );
201
    }
202
}
203