diff --git a/zaqarclient/transport/errors.py b/zaqarclient/transport/errors.py index ed8bcd40..163ca165 100644 --- a/zaqarclient/transport/errors.py +++ b/zaqarclient/transport/errors.py @@ -24,12 +24,24 @@ from zaqarclient import errors __all__ = ['TransportError', 'ResourceNotFound', 'MalformedRequest', 'UnauthorizedError', 'ForbiddenError', 'ServiceUnavailableError', - 'InternalServerError'] + 'InternalServerError', 'ConflictError'] class TransportError(errors.ZaqarError): """Base class for all transport errors.""" + code = None + + def __init__(self, title=None, description=None, text=None): + msg = 'Error response from Zaqar. Code: {0}.'.format(self.code) + if title: + msg += ' Title: {0}.'.format(title) + if description: + msg += ' Description: {0}.'.format(description) + if text: + msg += ' Text: {0}.'.format(text) + super(TransportError, self).__init__(msg) + class ResourceNotFound(TransportError): """Indicates that a resource is missing @@ -37,6 +49,8 @@ class ResourceNotFound(TransportError): This error maps to HTTP's 404 """ + code = 404 + class MalformedRequest(TransportError): """Indicates that a request is malformed @@ -44,6 +58,8 @@ class MalformedRequest(TransportError): This error maps to HTTP's 400 """ + code = 400 + class UnauthorizedError(TransportError): """Indicates that a request was not authenticated @@ -51,6 +67,8 @@ class UnauthorizedError(TransportError): This error maps to HTTP's 401 """ + code = 401 + class ForbiddenError(TransportError): """Indicates that a request is forbidden to access the particular resource @@ -58,6 +76,8 @@ class ForbiddenError(TransportError): This error maps to HTTP's 403 """ + code = 403 + class InternalServerError(TransportError): """Indicates that the server encountered an unexpected situation @@ -65,6 +85,8 @@ class InternalServerError(TransportError): This error maps to HTTP's 500 """ + code = 500 + class ServiceUnavailableError(TransportError): """Indicates that the server was unable to service the request @@ -72,9 +94,13 @@ class ServiceUnavailableError(TransportError): This error maps to HTTP's 503 """ + code = 503 + class ConflictError(TransportError): """Indicates that the server was unable to service the request This error maps to HTTP's 409 """ + + code = 409 diff --git a/zaqarclient/transport/http.py b/zaqarclient/transport/http.py index f09f7cba..07a49b70 100644 --- a/zaqarclient/transport/http.py +++ b/zaqarclient/transport/http.py @@ -96,14 +96,20 @@ class HttpTransport(base.Transport): data=request.content) if resp.status_code in self.http_to_zaqar: + kwargs = {} try: - msg = json.loads(resp.text)['description'] + error_body = json.loads(resp.text) + kwargs['title'] = error_body['title'] + kwargs['description'] = error_body['description'] except Exception: # TODO(flaper87): Log this exception # but don't stop raising the corresponding # exception - msg = '' - raise self.http_to_zaqar[resp.status_code](msg) + # Note(Eva-i): most of the error responses from Zaqar have + # dict with title and description in their bodies. If it's not + # the case, let's just show body text. + kwargs['text'] = resp.text + raise self.http_to_zaqar[resp.status_code](**kwargs) # NOTE(flaper87): This reads the whole content # and will consume any attempt of streaming.