diff --git a/lib/recurly/base_client.php b/lib/recurly/base_client.php index 39fa7f35..d93441a8 100644 --- a/lib/recurly/base_client.php +++ b/lib/recurly/base_client.php @@ -126,6 +126,7 @@ private function _getResponse(\Recurly\Request $request): \Recurly\Response 'response_headers' => $response->getHeaders() ] ); + $response->assertValid(); // throws \Recurly\RecurlyError if response is bad return $response; } diff --git a/lib/recurly/recurly_error.php b/lib/recurly/recurly_error.php index e924e48f..48db934d 100644 --- a/lib/recurly/recurly_error.php +++ b/lib/recurly/recurly_error.php @@ -54,13 +54,17 @@ public static function fromResponse(\Recurly\Response $response): \Recurly\Recur $api_error = \Recurly\Resources\ErrorMayHaveTransaction::fromResponse($response, $error); return new $klass($error->message, $api_error); } - } else { - $error_type = static::errorFromStatus($response->getStatusCode()); - $klass = static::titleize($error_type, '\\Recurly\\Errors\\'); - if (class_exists($klass)) { - return new $klass('An unexpected error has occurred'); - } } + + // "Content-type: application/json" may appear without a body after a HEAD request. + // If the above failed, try guessing from the status code. + $error_type = static::errorFromStatus($response->getStatusCode()); + $klass = static::titleize($error_type, '\\Recurly\\Errors\\'); + if (class_exists($klass)) { + return new $klass('An unexpected error has occurred'); + } + + // No valid error type was found, sorry. $klass = static::_defaultErrorType($response); return new $klass('An unexpected error has occurred'); diff --git a/lib/recurly/response.php b/lib/recurly/response.php index baf7a988..d59e3fdc 100644 --- a/lib/recurly/response.php +++ b/lib/recurly/response.php @@ -53,6 +53,16 @@ public function getRequest(): \Recurly\Request return $this->_request; } + /** + * Makes sure the response is valid. Throws RecurlyError otherwise. + */ + public function assertValid(): void + { + if ($this->_status_code < 200 || $this->_status_code >= 300) { + throw \Recurly\RecurlyError::fromResponse($this); + } + } + /** * Converts the Response into a \Recurly\RecurlyResource * @@ -60,16 +70,12 @@ public function getRequest(): \Recurly\Request */ public function toResource(): \Recurly\RecurlyResource { - if ($this->_status_code >= 200 && $this->_status_code < 300) { - if (empty($this->_response)) { - return \Recurly\RecurlyResource::fromEmpty($this); - } elseif (in_array($this->getContentType(), static::BINARY_TYPES)) { - return \Recurly\RecurlyResource::fromBinary($this->_response, $this); - } else { - return \Recurly\RecurlyResource::fromResponse($this); - } + if (empty($this->_response)) { + return \Recurly\RecurlyResource::fromEmpty($this); + } elseif (in_array($this->getContentType(), static::BINARY_TYPES)) { + return \Recurly\RecurlyResource::fromBinary($this->_response, $this); } else { - throw \Recurly\RecurlyError::fromResponse($this); + return \Recurly\RecurlyResource::fromResponse($this); } } diff --git a/tests/Response_Test.php b/tests/Response_Test.php index 6444190e..1481c68c 100644 --- a/tests/Response_Test.php +++ b/tests/Response_Test.php @@ -175,12 +175,12 @@ public function testToResourceEmpty(): void $this->assertInstanceOf(\Recurly\EmptyResource::class, $result); } - public function testToResourceError(): void + public function testAssertValid(): void { $this->expectException(\Recurly\RecurlyError::class); $response = new Response('', $this->request); $response->setHeaders(['HTTP/1.1 403 Forbidden']); - $result = $response->toResource(); + $result = $response->assertValid(); } public function testGetRawResponse(): void