Improve error feedback

When an error occur instead of just return the HTTP response code the
client will now try to extract the error message that contains the reason
of the problem and show it to the user in a user-friendly way (no codes
at all), the intention of this patch is to improve the usability of the
ironic client. Things like HTTP response codes can still be viewed when
used with the debug mode enabled ( -d ).

Change-Id: Ieca021cc0e0eabe91c13335c3062ef9622da3004
This commit is contained in:
Lucas Alvares Gomes 2013-10-02 16:16:31 +01:00
parent 6752ae8307
commit 489daf6710
3 changed files with 21 additions and 4 deletions

View File

@ -124,6 +124,16 @@ class HTTPClient(object):
base_url = _args[2]
return '%s/%s' % (base_url.rstrip('/'), url.lstrip('/'))
def _extract_error_message(self, body):
try:
body_json = json.loads(body)
if 'error_message' in body_json:
body_json = json.loads(body_json['error_message'])
if 'faultstring' in body_json:
return body_json['faultstring']
except ValueError:
pass
def _http_request(self, url, method, **kwargs):
"""Send an http request with the specified characteristics.
@ -156,6 +166,7 @@ class HTTPClient(object):
body_iter = ResponseBodyIterator(resp)
# Read body into string if it isn't obviously image data
body_str = None
if resp.getheader('content-type', None) != 'application/octet-stream':
body_str = ''.join([chunk for chunk in body_iter])
self.log_http_response(resp, body_str)
@ -165,7 +176,8 @@ class HTTPClient(object):
if 400 <= resp.status < 600:
LOG.warn("Request returned failure status.")
raise exc.from_response(resp)
err_msg = self._extract_error_message(body_str)
raise exc.from_response(resp, err_msg)
elif resp.status in (301, 302, 305):
# Redirected. Reissue the request to the new location.
return self._http_request(resp['location'], method, **kwargs)

View File

@ -46,7 +46,8 @@ class HTTPException(ClientException):
self.details = details
def __str__(self):
return "%s (HTTP %s)" % (self.__class__.__name__, self.code)
return self.details or "%s (HTTP %s)" % (self.__class__.__name__,
self.code)
class HTTPMultipleChoices(HTTPException):
@ -147,10 +148,10 @@ for obj_name in dir(sys.modules[__name__]):
_code_map[obj.code] = obj
def from_response(response):
def from_response(response, error=None):
"""Return an instance of an HTTPException based on httplib response."""
cls = _code_map.get(response.status, HTTPException)
return cls()
return cls(error)
class NoTokenLookupException(Exception):

View File

@ -184,6 +184,10 @@ class IronicShell(object):
level=logging.DEBUG)
httplib2.debuglevel = 1
else:
logging.basicConfig(
format="%(levelname)s %(message)s",
level=logging.CRITICAL)
def main(self, argv):
# Parse args once to find version