diff --git a/src/Exception/HttpException.php b/src/Exception/HttpException.php index 6508ba8..25a1f24 100644 --- a/src/Exception/HttpException.php +++ b/src/Exception/HttpException.php @@ -4,8 +4,8 @@ namespace Jenky\Atlas\Exception; -use Jenky\Atlas\Response; use Psr\Http\Client\ClientExceptionInterface; +use Psr\Http\Message\ResponseInterface; use RuntimeException; class HttpException extends RuntimeException implements ClientExceptionInterface @@ -13,13 +13,20 @@ class HttpException extends RuntimeException implements ClientExceptionInterface /** * The response instance. * - * @var \Jenky\Atlas\Response + * @var ResponseInterface */ private $response; - public function __construct(Response $response) - { - parent::__construct($this->prepareMessage($response), $response->status()); + public function __construct( + ResponseInterface $response, + string $message = '', + ?\Throwable $previous = null + ) { + parent::__construct( + $message ?: $this->prepareMessage($response), + $response->getStatusCode(), + $previous + ); $this->response = $response; } @@ -27,7 +34,7 @@ public function __construct(Response $response) /** * Get the response. */ - public function response(): Response + public function getResponse(): ResponseInterface { return $this->response; } @@ -35,10 +42,10 @@ public function response(): Response /** * Prepare the exception message. */ - protected function prepareMessage(Response $response): string + protected function prepareMessage(ResponseInterface $response): string { - return sprintf('HTTP request returned status code %d %s: %s', - $response->status(), $response->reason(), $response->body() + return sprintf('HTTP request returned status code %d %s', + $response->getStatusCode(), $response->getReasonPhrase() ); } } diff --git a/src/Exception/NotDecodableException.php b/src/Exception/NotDecodableException.php index 5834c0c..3feeae0 100644 --- a/src/Exception/NotDecodableException.php +++ b/src/Exception/NotDecodableException.php @@ -4,7 +4,9 @@ namespace Jenky\Atlas\Exception; -class NotDecodableException extends \LogicException +use Psr\Http\Client\ClientExceptionInterface; + +class NotDecodableException extends \LogicException implements ClientExceptionInterface { public static function create(string $message = 'Unable to decode the response body.'): self { diff --git a/src/Exception/RequestException.php b/src/Exception/RequestException.php new file mode 100644 index 0000000..28d8ed4 --- /dev/null +++ b/src/Exception/RequestException.php @@ -0,0 +1,44 @@ +getStatusCode() : 0; + parent::__construct($message, $code, $previous); + $this->request = $request; + $this->response = $response; + } + + public function getRequest(): RequestInterface + { + return $this->request; + } + + public function getResponse(): ?ResponseInterface + { + return $this->response; + } +} diff --git a/src/Exception/RequestRetryFailedException.php b/src/Exception/RequestRetryFailedException.php index b22938d..07d3d05 100644 --- a/src/Exception/RequestRetryFailedException.php +++ b/src/Exception/RequestRetryFailedException.php @@ -4,6 +4,6 @@ namespace Jenky\Atlas\Exception; -final class RequestRetryFailedException extends \RuntimeException +class RequestRetryFailedException extends RequestException { } diff --git a/src/Exception/TooManyRedirectsException.php b/src/Exception/TooManyRedirectsException.php index afcdca6..c80146c 100644 --- a/src/Exception/TooManyRedirectsException.php +++ b/src/Exception/TooManyRedirectsException.php @@ -4,6 +4,6 @@ namespace Jenky\Atlas\Exception; -class TooManyRedirectsException extends \Exception +class TooManyRedirectsException extends RequestException { } diff --git a/src/Middleware/FollowRedirects.php b/src/Middleware/FollowRedirects.php index 53f815a..d55a6bf 100644 --- a/src/Middleware/FollowRedirects.php +++ b/src/Middleware/FollowRedirects.php @@ -63,17 +63,17 @@ public function __invoke(RequestInterface $request, callable $next): ResponseInt return $response; } - $this->guardMax(); + $this->guardMax($request, $response); return $this($this->modifyRequest($request, $response), $next); } - private function guardMax(): void + private function guardMax(RequestInterface $request, ResponseInterface $response): void { ++$this->redirects; if ($this->redirects > $this->max) { - throw new TooManyRedirectsException(''); + throw new TooManyRedirectsException("Will not follow more than {$this->max} redirects", $request, $response); } } diff --git a/src/Middleware/RetryRequests.php b/src/Middleware/RetryRequests.php index 68e2ab5..5e8c041 100644 --- a/src/Middleware/RetryRequests.php +++ b/src/Middleware/RetryRequests.php @@ -44,7 +44,11 @@ public function __invoke(RequestInterface $request, callable $next): ResponseInt if ($stop) { if ($this->context->throwable()) { - throw new RequestRetryFailedException(sprintf('Maximum %d retries reached.', $this->context->maxRetries())); + throw new RequestRetryFailedException( + sprintf('Maximum %d retries reached.', $this->context->maxRetries()), + $request, + $response, + ); } return $response; diff --git a/src/Response.php b/src/Response.php index 52759da..24d6119 100644 --- a/src/Response.php +++ b/src/Response.php @@ -199,11 +199,11 @@ public function getResponse(): ResponseInterface public function toException(): ?HttpException { if ($this->clientError()) { - return new Exception\ClientRequestException($this); + return new Exception\ClientRequestException($this->response); } if ($this->serverError()) { - return new Exception\ServerRequestException($this); + return new Exception\ServerRequestException($this->response); } return null;