update to PHP-8.1
[m6w6/seekat] / lib / Exception / RequestException.php
1 <?php
2
3 namespace seekat\Exception;
4
5 use http\{Client\Response, Header};
6 use seekat\Exception;
7
8 /**
9 * @code-coverage-ignore
10 */
11 class RequestException extends \Exception implements Exception {
12 /**
13 * JSON errors
14 * @var array
15 */
16 private $errors = [];
17
18 /**
19 * The response of the request which caused the exception
20 * @var Response
21 */
22 private $response;
23
24 /**
25 * @param Response $response
26 */
27 function __construct(Response $response) {
28 $this->response = $response;
29
30 if (($h = $response->getHeader("Content-Type", Header::class))
31 && $h->match("application/json", Header::MATCH_WORD)
32 && $failure = json_decode($response->getBody())) {
33 $message = $failure->message;
34 if (isset($failure->errors)) {
35 $this->errors = (array) $failure->errors;
36 }
37 } else {
38 $message = trim($response->getBody()->toString());
39 }
40
41 if (!strlen($message)) {
42 $message = $response->getTransferInfo("error");
43 }
44 if (!strlen($message)) {
45 $message = $response->getResponseStatus();
46 }
47
48 parent::__construct($message, $response->getResponseCode(), null);
49 }
50
51 /**
52 * Get JSON errors
53 * @return array
54 */
55 function getErrors() : array {
56 return $this->errors;
57 }
58
59 /**
60 * @return Response
61 */
62 function getResponse() : Response {
63 return $this->response;
64 }
65
66 /**
67 * Combine any errors into a single string
68 * @staticvar array $reasons
69 * @return string
70 */
71 function getErrorsAsString() {
72 static $reasons = [
73 "missing" => "The resource %1\$s does not exist\n",
74 "missing_field" => "Missing field %2\$s of resource %1\$s\n",
75 "invalid" => "Invalid formatting of field %2\$s of resource %1\$s\n",
76 "already_exists" => "A resource %1\$s with the same value of field %2\$s already exists\n",
77 ];
78
79 if (!$this->errors) {
80 return $this->response;
81 }
82
83 $errors = "JSON errors:\n";
84 foreach ($this->errors as $error) {
85 if ($error->code === "custom") {
86 $errors .= $error->message . "\n";
87 } else {
88 $errors .= sprintf($reasons[$error->code], $error->resource, $error->field);
89 }
90 }
91 return $errors;
92 }
93
94 /**
95 * @return string
96 */
97 function __toString() : string {
98 return parent::__toString() . "\n". $this->getErrorsAsString();
99 }
100 }