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