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