Make TransportErrors more descriptive

Problems:

1. In some cases no information is provided for the CLI user when
these exceptions are raised:
https://github.com/openstack/python-zaqarclient/blob/master/zaqarclient/
transport/http.py#L30.
For example, try "openstack pool show unexisting_pool". You will see
just blank line. It is because the server returns no message in the 404
response body. And the user sees the blank line.

2. Most of the error responses from Zaqar have bodies in
title-description format. TransportErrors can only show descriptions
from these responses. It's better to include also titles in the
client's exception messages.

3. Some of the error responses from Zaqar are not in title-description
format, but still have some info in their bodies. It's better to include
this info to the client's exception message.

Solution:

This patch makes all exceptions in zaqarclient/transport/errors.py show
at least error response code. The patch TransportErrors properly gather
the info from Zaqar's error response bodies and show it.

Partial-Bug: 1542804

Change-Id: Ie2cc3081a5dd7c4f21c29bdf78a9bad76b515121
This commit is contained in:
Eva Balycheva 2016-02-16 23:51:10 +03:00
parent 8eaf813984
commit 87f0fb56b3
2 changed files with 36 additions and 4 deletions

View File

@ -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

View File

@ -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.