annotate vendor/guzzlehttp/guzzle/src/Exception/RequestException.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 4c8ae668cc8c
children
rev   line source
Chris@0 1 <?php
Chris@0 2 namespace GuzzleHttp\Exception;
Chris@0 3
Chris@0 4 use Psr\Http\Message\RequestInterface;
Chris@0 5 use Psr\Http\Message\ResponseInterface;
Chris@0 6 use GuzzleHttp\Promise\PromiseInterface;
Chris@0 7 use Psr\Http\Message\UriInterface;
Chris@0 8
Chris@0 9 /**
Chris@0 10 * HTTP Request exception
Chris@0 11 */
Chris@0 12 class RequestException extends TransferException
Chris@0 13 {
Chris@0 14 /** @var RequestInterface */
Chris@0 15 private $request;
Chris@0 16
Chris@0 17 /** @var ResponseInterface */
Chris@0 18 private $response;
Chris@0 19
Chris@0 20 /** @var array */
Chris@0 21 private $handlerContext;
Chris@0 22
Chris@0 23 public function __construct(
Chris@0 24 $message,
Chris@0 25 RequestInterface $request,
Chris@0 26 ResponseInterface $response = null,
Chris@0 27 \Exception $previous = null,
Chris@0 28 array $handlerContext = []
Chris@0 29 ) {
Chris@0 30 // Set the code of the exception if the response is set and not future.
Chris@0 31 $code = $response && !($response instanceof PromiseInterface)
Chris@0 32 ? $response->getStatusCode()
Chris@0 33 : 0;
Chris@0 34 parent::__construct($message, $code, $previous);
Chris@0 35 $this->request = $request;
Chris@0 36 $this->response = $response;
Chris@0 37 $this->handlerContext = $handlerContext;
Chris@0 38 }
Chris@0 39
Chris@0 40 /**
Chris@0 41 * Wrap non-RequestExceptions with a RequestException
Chris@0 42 *
Chris@0 43 * @param RequestInterface $request
Chris@0 44 * @param \Exception $e
Chris@0 45 *
Chris@0 46 * @return RequestException
Chris@0 47 */
Chris@0 48 public static function wrapException(RequestInterface $request, \Exception $e)
Chris@0 49 {
Chris@0 50 return $e instanceof RequestException
Chris@0 51 ? $e
Chris@0 52 : new RequestException($e->getMessage(), $request, null, $e);
Chris@0 53 }
Chris@0 54
Chris@0 55 /**
Chris@0 56 * Factory method to create a new exception with a normalized error message
Chris@0 57 *
Chris@0 58 * @param RequestInterface $request Request
Chris@0 59 * @param ResponseInterface $response Response received
Chris@0 60 * @param \Exception $previous Previous exception
Chris@0 61 * @param array $ctx Optional handler context.
Chris@0 62 *
Chris@0 63 * @return self
Chris@0 64 */
Chris@0 65 public static function create(
Chris@0 66 RequestInterface $request,
Chris@0 67 ResponseInterface $response = null,
Chris@0 68 \Exception $previous = null,
Chris@0 69 array $ctx = []
Chris@0 70 ) {
Chris@0 71 if (!$response) {
Chris@0 72 return new self(
Chris@0 73 'Error completing request',
Chris@0 74 $request,
Chris@0 75 null,
Chris@0 76 $previous,
Chris@0 77 $ctx
Chris@0 78 );
Chris@0 79 }
Chris@0 80
Chris@0 81 $level = (int) floor($response->getStatusCode() / 100);
Chris@0 82 if ($level === 4) {
Chris@0 83 $label = 'Client error';
Chris@0 84 $className = ClientException::class;
Chris@0 85 } elseif ($level === 5) {
Chris@0 86 $label = 'Server error';
Chris@0 87 $className = ServerException::class;
Chris@0 88 } else {
Chris@0 89 $label = 'Unsuccessful request';
Chris@0 90 $className = __CLASS__;
Chris@0 91 }
Chris@0 92
Chris@0 93 $uri = $request->getUri();
Chris@0 94 $uri = static::obfuscateUri($uri);
Chris@0 95
Chris@0 96 // Client Error: `GET /` resulted in a `404 Not Found` response:
Chris@0 97 // <html> ... (truncated)
Chris@0 98 $message = sprintf(
Chris@0 99 '%s: `%s %s` resulted in a `%s %s` response',
Chris@0 100 $label,
Chris@0 101 $request->getMethod(),
Chris@0 102 $uri,
Chris@0 103 $response->getStatusCode(),
Chris@0 104 $response->getReasonPhrase()
Chris@0 105 );
Chris@0 106
Chris@0 107 $summary = static::getResponseBodySummary($response);
Chris@0 108
Chris@0 109 if ($summary !== null) {
Chris@0 110 $message .= ":\n{$summary}\n";
Chris@0 111 }
Chris@0 112
Chris@0 113 return new $className($message, $request, $response, $previous, $ctx);
Chris@0 114 }
Chris@0 115
Chris@0 116 /**
Chris@0 117 * Get a short summary of the response
Chris@0 118 *
Chris@0 119 * Will return `null` if the response is not printable.
Chris@0 120 *
Chris@0 121 * @param ResponseInterface $response
Chris@0 122 *
Chris@0 123 * @return string|null
Chris@0 124 */
Chris@0 125 public static function getResponseBodySummary(ResponseInterface $response)
Chris@0 126 {
Chris@0 127 $body = $response->getBody();
Chris@0 128
Chris@0 129 if (!$body->isSeekable()) {
Chris@0 130 return null;
Chris@0 131 }
Chris@0 132
Chris@0 133 $size = $body->getSize();
Chris@0 134
Chris@0 135 if ($size === 0) {
Chris@0 136 return null;
Chris@0 137 }
Chris@0 138
Chris@0 139 $summary = $body->read(120);
Chris@0 140 $body->rewind();
Chris@0 141
Chris@0 142 if ($size > 120) {
Chris@0 143 $summary .= ' (truncated...)';
Chris@0 144 }
Chris@0 145
Chris@0 146 // Matches any printable character, including unicode characters:
Chris@0 147 // letters, marks, numbers, punctuation, spacing, and separators.
Chris@0 148 if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $summary)) {
Chris@0 149 return null;
Chris@0 150 }
Chris@0 151
Chris@0 152 return $summary;
Chris@0 153 }
Chris@0 154
Chris@0 155 /**
Chris@0 156 * Obfuscates URI if there is an username and a password present
Chris@0 157 *
Chris@0 158 * @param UriInterface $uri
Chris@0 159 *
Chris@0 160 * @return UriInterface
Chris@0 161 */
Chris@0 162 private static function obfuscateUri($uri)
Chris@0 163 {
Chris@0 164 $userInfo = $uri->getUserInfo();
Chris@0 165
Chris@0 166 if (false !== ($pos = strpos($userInfo, ':'))) {
Chris@0 167 return $uri->withUserInfo(substr($userInfo, 0, $pos), '***');
Chris@0 168 }
Chris@0 169
Chris@0 170 return $uri;
Chris@0 171 }
Chris@0 172
Chris@0 173 /**
Chris@0 174 * Get the request that caused the exception
Chris@0 175 *
Chris@0 176 * @return RequestInterface
Chris@0 177 */
Chris@0 178 public function getRequest()
Chris@0 179 {
Chris@0 180 return $this->request;
Chris@0 181 }
Chris@0 182
Chris@0 183 /**
Chris@0 184 * Get the associated response
Chris@0 185 *
Chris@0 186 * @return ResponseInterface|null
Chris@0 187 */
Chris@0 188 public function getResponse()
Chris@0 189 {
Chris@0 190 return $this->response;
Chris@0 191 }
Chris@0 192
Chris@0 193 /**
Chris@0 194 * Check if a response was received
Chris@0 195 *
Chris@0 196 * @return bool
Chris@0 197 */
Chris@0 198 public function hasResponse()
Chris@0 199 {
Chris@0 200 return $this->response !== null;
Chris@0 201 }
Chris@0 202
Chris@0 203 /**
Chris@0 204 * Get contextual information about the error from the underlying handler.
Chris@0 205 *
Chris@0 206 * The contents of this array will vary depending on which handler you are
Chris@0 207 * using. It may also be just an empty array. Relying on this data will
Chris@0 208 * couple you to a specific handler, but can give more debug information
Chris@0 209 * when needed.
Chris@0 210 *
Chris@0 211 * @return array
Chris@0 212 */
Chris@0 213 public function getHandlerContext()
Chris@0 214 {
Chris@0 215 return $this->handlerContext;
Chris@0 216 }
Chris@0 217 }