1 <?php 2 3 namespace GuzzleHttp\Exception; 4 5 use GuzzleHttp\BodySummarizer; 6 use GuzzleHttp\BodySummarizerInterface; 7 use Psr\Http\Client\RequestExceptionInterface; 8 use Psr\Http\Message\RequestInterface; 9 use Psr\Http\Message\ResponseInterface; 10 use Psr\Http\Message\UriInterface; 11 12 /** 13 * HTTP Request exception 14 */ 15 class RequestException extends TransferException implements RequestExceptionInterface 16 { 17 /** 18 * @var RequestInterface 19 */ 20 private $request; 21 22 /** 23 * @var ResponseInterface|null 24 */ 25 private $response; 26 27 /** 28 * @var array 29 */ 30 private $handlerContext; 31 32 public function __construct( 33 string $message, 34 RequestInterface $request, 35 ResponseInterface $response = null, 36 \Throwable $previous = null, 37 array $handlerContext = [] 38 ) { 39 // Set the code of the exception if the response is set and not future. 40 $code = $response ? $response->getStatusCode() : 0; 41 parent::__construct($message, $code, $previous); 42 $this->request = $request; 43 $this->response = $response; 44 $this->handlerContext = $handlerContext; 45 } 46 47 /** 48 * Wrap non-RequestExceptions with a RequestException 49 */ 50 public static function wrapException(RequestInterface $request, \Throwable $e): RequestException 51 { 52 return $e instanceof RequestException ? $e : new RequestException($e->getMessage(), $request, null, $e); 53 } 54 55 /** 56 * Factory method to create a new exception with a normalized error message 57 * 58 * @param RequestInterface $request Request sent 59 * @param ResponseInterface $response Response received 60 * @param \Throwable|null $previous Previous exception 61 * @param array $handlerContext Optional handler context 62 * @param BodySummarizerInterface|null $bodySummarizer Optional body summarizer 63 */ 64 public static function create( 65 RequestInterface $request, 66 ResponseInterface $response = null, 67 \Throwable $previous = null, 68 array $handlerContext = [], 69 BodySummarizerInterface $bodySummarizer = null 70 ): self { 71 if (!$response) { 72 return new self( 73 'Error completing request', 74 $request, 75 null, 76 $previous, 77 $handlerContext 78 ); 79 } 80 81 $level = (int) \floor($response->getStatusCode() / 100); 82 if ($level === 4) { 83 $label = 'Client error'; 84 $className = ClientException::class; 85 } elseif ($level === 5) { 86 $label = 'Server error'; 87 $className = ServerException::class; 88 } else { 89 $label = 'Unsuccessful request'; 90 $className = __CLASS__; 91 } 92 93 $uri = $request->getUri(); 94 $uri = static::obfuscateUri($uri); 95 96 // Client Error: `GET /` resulted in a `404 Not Found` response: 97 // <html> ... (truncated) 98 $message = \sprintf( 99 '%s: `%s %s` resulted in a `%s %s` response', 100 $label, 101 $request->getMethod(), 102 $uri->__toString(), 103 $response->getStatusCode(), 104 $response->getReasonPhrase() 105 ); 106 107 $summary = ($bodySummarizer ?? new BodySummarizer())->summarize($response); 108 109 if ($summary !== null) { 110 $message .= ":\n{$summary}\n"; 111 } 112 113 return new $className($message, $request, $response, $previous, $handlerContext); 114 } 115 116 /** 117 * Obfuscates URI if there is a username and a password present 118 */ 119 private static function obfuscateUri(UriInterface $uri): UriInterface 120 { 121 $userInfo = $uri->getUserInfo(); 122 123 if (false !== ($pos = \strpos($userInfo, ':'))) { 124 return $uri->withUserInfo(\substr($userInfo, 0, $pos), '***'); 125 } 126 127 return $uri; 128 } 129 130 /** 131 * Get the request that caused the exception 132 */ 133 public function getRequest(): RequestInterface 134 { 135 return $this->request; 136 } 137 138 /** 139 * Get the associated response 140 */ 141 public function getResponse(): ?ResponseInterface 142 { 143 return $this->response; 144 } 145 146 /** 147 * Check if a response was received 148 */ 149 public function hasResponse(): bool 150 { 151 return $this->response !== null; 152 } 153 154 /** 155 * Get contextual information about the error from the underlying handler. 156 * 157 * The contents of this array will vary depending on which handler you are 158 * using. It may also be just an empty array. Relying on this data will 159 * couple you to a specific handler, but can give more debug information 160 * when needed. 161 */ 162 public function getHandlerContext(): array 163 { 164 return $this->handlerContext; 165 } 166 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body