4
4
5
5
namespace ApiSkeletons \Laravel \ApiProblem ;
6
6
7
- use Exception ;
8
7
use ApiSkeletons \Laravel \ApiProblem \Exception \InvalidArgumentException ;
9
8
use ApiSkeletons \Laravel \ApiProblem \Exception \ProblemExceptionInterface ;
9
+ use Exception ;
10
10
use Throwable ;
11
11
12
12
use function array_key_exists ;
13
13
use function array_keys ;
14
14
use function array_merge ;
15
+ use function assert ;
15
16
use function count ;
16
17
use function get_class ;
17
18
use function in_array ;
@@ -33,45 +34,37 @@ class ApiProblem
33
34
/**
34
35
* Additional details to include in report.
35
36
*
36
- * @var array
37
+ * @var string[]
37
38
*/
38
- protected $ additionalDetails = [];
39
+ protected array $ additionalDetails = [];
39
40
40
41
/**
41
42
* URL describing the problem type; defaults to HTTP status codes.
42
- *
43
- * @var string
44
43
*/
45
- protected $ type = 'http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html ' ;
44
+ protected string $ type = 'http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html ' ;
46
45
47
46
/**
48
47
* Description of the specific problem.
49
- *
50
- * @var string|Exception|Throwable
51
48
*/
52
- protected $ detail = '' ;
49
+ protected string | Throwable | Throwable $ detail = '' ;
53
50
54
51
/**
55
52
* Whether or not to include a stack trace and previous
56
53
* exceptions when an exception is provided for the detail.
57
- *
58
- * @var bool
59
54
*/
60
- protected $ detailIncludesStackTrace = false ;
55
+ protected bool $ detailIncludesStackTrace = false ;
61
56
62
57
/**
63
58
* HTTP status for the error.
64
- *
65
- * @var int
66
59
*/
67
- protected $ status ;
60
+ protected int $ status ;
68
61
69
62
/**
70
63
* Normalized property names for overloading.
71
64
*
72
- * @var array
65
+ * @var string[]
73
66
*/
74
- protected $ normalizedProperties = [
67
+ protected array $ normalizedProperties = [
75
68
'type ' => 'type ' ,
76
69
'status ' => 'status ' ,
77
70
'title ' => 'title ' ,
@@ -81,9 +74,9 @@ class ApiProblem
81
74
/**
82
75
* Status titles for common problems.
83
76
*
84
- * @var array
77
+ * @var string[]
85
78
*/
86
- protected $ problemStatusTitles = [
79
+ protected array $ problemStatusTitles = [
87
80
// CLIENT ERROR
88
81
400 => 'Bad Request ' ,
89
82
401 => 'Unauthorized ' ,
@@ -127,32 +120,28 @@ class ApiProblem
127
120
128
121
/**
129
122
* Title of the error.
130
- *
131
- * @var string
132
123
*/
133
- protected $ title ;
124
+ protected string $ title ;
134
125
135
126
/**
136
127
* Create an instance using the provided information. If nothing is
137
128
* provided for the type field, the class default will be used;
138
129
* if the status matches any known, the title field will be selected
139
130
* from $problemStatusTitles as a result.
140
131
*
141
- * @param int|string $status
142
- * @param string|Exception|Throwable $detail
143
- * @param string $type
144
- * @param string $title
145
- * @param array $additional
132
+ * @param string[] $additional
146
133
*/
147
- public function __construct ($ status , $ detail , $ type = null , $ title = null , array $ additional = [])
134
+ public function __construct (int | string $ status , string | Throwable | Throwable $ detail , ? string $ type = null , ? string $ title = null , array $ additional = [])
148
135
{
149
136
if ($ detail instanceof ProblemExceptionInterface) {
150
- if (null === $ type ) {
137
+ if ($ type === null ) {
151
138
$ type = $ detail ->getType ();
152
139
}
153
- if (null === $ title ) {
140
+
141
+ if ($ title === null ) {
154
142
$ title = $ detail ->getTitle ();
155
143
}
144
+
156
145
if (empty ($ additional )) {
157
146
$ additional = $ detail ->getAdditionalDetails ();
158
147
}
@@ -171,7 +160,7 @@ public function __construct($status, $detail, $type = null, $title = null, array
171
160
$ this ->detail = $ detail ;
172
161
$ this ->title = $ title ;
173
162
174
- if (null !== $ type ) {
163
+ if ($ type !== null ) {
175
164
$ this ->type = $ type ;
176
165
}
177
166
@@ -181,11 +170,9 @@ public function __construct($status, $detail, $type = null, $title = null, array
181
170
/**
182
171
* Retrieve properties.
183
172
*
184
- * @param string $name
185
- * @return mixed
186
173
* @throws InvalidArgumentException
187
174
*/
188
- public function __get ($ name )
175
+ public function __get (string $ name ): mixed
189
176
{
190
177
$ normalized = strtolower ($ name );
191
178
if (in_array ($ normalized , array_keys ($ this ->normalizedProperties ))) {
@@ -211,28 +198,26 @@ public function __get($name)
211
198
/**
212
199
* Cast to an array.
213
200
*
214
- * @return array
201
+ * @return string[]
215
202
*/
216
- public function toArray ()
203
+ public function toArray (): array
217
204
{
218
205
$ problem = [
219
206
'type ' => $ this ->type ,
220
207
'title ' => $ this ->getTitle (),
221
208
'status ' => $ this ->getStatus (),
222
209
'detail ' => $ this ->getDetail (),
223
210
];
211
+
224
212
// Required fields should always overwrite additional fields
225
213
return array_merge ($ this ->additionalDetails , $ problem );
226
214
}
227
215
228
216
/**
229
217
* Set the flag indicating whether an exception detail should include a
230
218
* stack trace and previous exception information.
231
- *
232
- * @param bool $flag
233
- * @return ApiProblem
234
219
*/
235
- public function setDetailIncludesStackTrace ($ flag )
220
+ public function setDetailIncludesStackTrace (bool $ flag ): ApiProblem
236
221
{
237
222
$ this ->detailIncludesStackTrace = (bool ) $ flag ;
238
223
@@ -244,10 +229,8 @@ public function setDetailIncludesStackTrace($flag)
244
229
*
245
230
* If an exception was provided, creates the detail message from it;
246
231
* otherwise, detail as provided is used.
247
- *
248
- * @return string
249
232
*/
250
- protected function getDetail ()
233
+ protected function getDetail (): string
251
234
{
252
235
if ($ this ->detail instanceof Throwable || $ this ->detail instanceof Exception) {
253
236
return $ this ->createDetailFromException ();
@@ -281,17 +264,15 @@ protected function getStatus(): int
281
264
* string 'Unknown'.
282
265
*
283
266
* Otherwise, use the title provided.
284
- *
285
- * @return string
286
267
*/
287
- protected function getTitle ()
268
+ protected function getTitle (): string
288
269
{
289
- if (null !== $ this ->title ) {
270
+ if ($ this ->title !== null ) {
290
271
return $ this ->title ;
291
272
}
292
273
293
274
if (
294
- null === $ this ->title
275
+ $ this ->title === null
295
276
&& $ this ->type === 'http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html '
296
277
&& array_key_exists ($ this ->getStatus (), $ this ->problemStatusTitles )
297
278
) {
@@ -302,7 +283,7 @@ protected function getTitle()
302
283
return get_class ($ this ->detail );
303
284
}
304
285
305
- if (null === $ this ->title ) {
286
+ if ($ this ->title === null ) {
306
287
return 'Unknown ' ;
307
288
}
308
289
@@ -311,13 +292,11 @@ protected function getTitle()
311
292
312
293
/**
313
294
* Create detail message from an exception.
314
- *
315
- * @return string
316
295
*/
317
- protected function createDetailFromException ()
296
+ protected function createDetailFromException (): string
318
297
{
319
- /** @var Exception|Throwable $e */
320
298
$ e = $ this ->detail ;
299
+ assert ($ e instanceof Exception || $ e instanceof Throwable);
321
300
322
301
if (! $ this ->detailIncludesStackTrace ) {
323
302
return $ e ->getMessage ();
@@ -336,6 +315,7 @@ protected function createDetailFromException()
336
315
];
337
316
$ e = $ e ->getPrevious ();
338
317
}
318
+
339
319
if (count ($ previous )) {
340
320
$ this ->additionalDetails ['exception_stack ' ] = $ previous ;
341
321
}
@@ -345,13 +325,11 @@ protected function createDetailFromException()
345
325
346
326
/**
347
327
* Create HTTP status from an exception.
348
- *
349
- * @return int|string
350
328
*/
351
- protected function createStatusFromException ()
329
+ protected function createStatusFromException (): int | string
352
330
{
353
- /** @var Exception|Throwable $e */
354
- $ e = $ this -> detail ;
331
+ $ e = $ this -> detail ;
332
+ assert ( $ e instanceof Exception || $ e instanceof Throwable) ;
355
333
$ status = $ e ->getCode ();
356
334
357
335
if ($ status ) {
0 commit comments