Created
April 30, 2014 17:02
-
-
Save jamiehannaford/0a085d4b1507308b0190 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace OpenStack\Common\Transport\Exception; | |
use GuzzleHttp\Message\RequestInterface; | |
use GuzzleHttp\Message\ResponseInterface; | |
use OpenStack\Common\Exception; | |
class RequestException extends Exception | |
{ | |
/** @var \GuzzleHttp\Message\RequestInterface */ | |
protected $request; | |
/** @var \GuzzleHttp\Message\ResponseInterface */ | |
protected $response; | |
/** | |
* Construct this exception like any other, but also inject Request and | |
* Response objects in case the user needs them for debugging. | |
* | |
* @param string $errorMessage Human-readable explanation of error | |
* @param RequestInterface $request The failed request | |
* @param ResponseInterface $response The API's response | |
*/ | |
public function __construct($errorMessage, RequestInterface $request, ResponseInterface $response) | |
{ | |
parent::__construct($errorMessage); | |
$this->request = $request; | |
$this->response = $response; | |
} | |
/** | |
* Factory method that creates an appropriate Exception object based on the | |
* Response's status code. The message is constructed here also. | |
* | |
* @param RequestInterface $request The failed request | |
* @param ResponseInterface $response The API's response | |
* @return self | |
*/ | |
public static function create(RequestInterface $request, ResponseInterface $response) | |
{ | |
$label = 'A HTTP error occurred'; | |
$status = $response->getStatusCode(); | |
switch ($status) { | |
case '401': | |
$class = self::prependNamespace('UnauthorizedException'); | |
break; | |
case '403': | |
$class = self::prependNamespace('ForbiddenException'); | |
break; | |
case '404': | |
$class = self::prependNamespace('ResourceNotFoundException'); | |
break; | |
case '405': | |
$class = self::prependNamespace('MethodNotAllowedException'); | |
break; | |
case '409': | |
$class = self::prependNamespace('ConflictException'); | |
break; | |
case '411': | |
$class = self::prependNamespace('LengthRequiredException'); | |
break; | |
case '422': | |
$class = self::prependNamespace('UnprocessableEntityException'); | |
break; | |
case '500': | |
$class = self::prependNamespace('ServerException'); | |
break; | |
} | |
$message = sprintf( | |
"%s\n[Status] %s (%s)\n[Message] %s", $label, | |
$status, $response->getReasonPhrase(), (string) $response->getBody() | |
); | |
// For all other errors, throw a generic Exception | |
if (!isset($class)) { | |
throw new Exception($message); | |
} | |
return new $class($message, $request, $response); | |
} | |
protected static function prependNamespace($class) | |
{ | |
return sprintf("%s\\%s", __NAMESPACE__, $class); | |
} | |
public function getResponse() | |
{ | |
return $this->response; | |
} | |
public function getRequest() | |
{ | |
return $this->request; | |
} | |
} |
In that case, what about creating a default
case that returns new self($message, $request, $response);
?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I agree about the method name, I'll change it to
self::prependNamespaceTo
.Adding a
default
block won't work because the generic exception class has different constructor args - so it needs to be instantiated in a different way. Another option might be:I see what you mean about making the
RequestException
abstract - but I'm not sure we'll need to do it. Say for example we encounter a HTTP4xx
or5xx
error that does not have its own concrete exception, we'd probably throw a genericRequestException
.