Pass response body down into RestClientExceptions

This commit adds support to RestClientException objects to store the
response body as a local attr. Additionally it modifies all the uses
of the subclassed RestClientExceptions in the base rest client to
store the response body on each error type.

This is done in order to check the content in some occasion that
additional error details are coming back from a service in the body.
It will be useful to have the resp_body passed into the exception so
that it can be used in additional checks.

Change-Id: Ie1bb259e7e683081f0ad127617acc8deb98467c0
This commit is contained in:
Endre Karlson
2015-05-18 14:48:44 +02:00
committed by Endre Karlson
parent 15736e593d
commit f93048334c
3 changed files with 93 additions and 6 deletions

View File

@@ -436,7 +436,10 @@ class RestClient(object):
req_body, resp_body, caller_name, extra)
def _parse_resp(self, body):
body = json.loads(body)
try:
body = json.loads(body)
except ValueError:
return body
# We assume, that if the first value of the deserialized body's
# item set is a dict or a list, that we just return the first value
@@ -666,12 +669,18 @@ class RestClient(object):
raise exceptions.InvalidContentType(str(resp.status))
if resp.status == 401:
if parse_resp:
resp_body = self._parse_resp(resp_body)
raise exceptions.Unauthorized(resp_body)
if resp.status == 403:
if parse_resp:
resp_body = self._parse_resp(resp_body)
raise exceptions.Forbidden(resp_body)
if resp.status == 404:
if parse_resp:
resp_body = self._parse_resp(resp_body)
raise exceptions.NotFound(resp_body)
if resp.status == 400:
@@ -731,7 +740,7 @@ class RestClient(object):
if resp.status == 501:
raise exceptions.NotImplemented(message)
else:
raise exceptions.ServerFault(message)
raise exceptions.ServerFault(resp_body, message=message)
if resp.status >= 400:
raise exceptions.UnexpectedResponseCode(str(resp.status))

View File

@@ -47,7 +47,10 @@ class TempestException(Exception):
class RestClientException(TempestException,
testtools.TestCase.failureException):
pass
def __init__(self, resp_body, *args, **kwargs):
self.resp_body = resp_body
message = kwargs.get("message", resp_body)
super(RestClientException, self).__init__(message, *args, **kwargs)
class InvalidHttpSuccessCode(RestClientException):

View File

@@ -361,11 +361,86 @@ class TestRestClientErrorCheckerJSON(base.TestCase):
self.rest_client._error_checker,
**self.set_data("501"))
def test_response_400_with_dict(self):
r_body = '{"resp_body": {"err": "fake_resp_body"}}'
e = self.assertRaises(exceptions.BadRequest,
self.rest_client._error_checker,
**self.set_data("400", r_body=r_body))
if self.c_type == 'application/json':
expected = {"err": "fake_resp_body"}
else:
expected = r_body
self.assertEqual(expected, e.resp_body)
def test_response_401_with_dict(self):
r_body = '{"resp_body": {"err": "fake_resp_body"}}'
e = self.assertRaises(exceptions.Unauthorized,
self.rest_client._error_checker,
**self.set_data("401", r_body=r_body))
if self.c_type == 'application/json':
expected = {"err": "fake_resp_body"}
else:
expected = r_body
self.assertEqual(expected, e.resp_body)
def test_response_403_with_dict(self):
r_body = '{"resp_body": {"err": "fake_resp_body"}}'
e = self.assertRaises(exceptions.Forbidden,
self.rest_client._error_checker,
**self.set_data("403", r_body=r_body))
if self.c_type == 'application/json':
expected = {"err": "fake_resp_body"}
else:
expected = r_body
self.assertEqual(expected, e.resp_body)
def test_response_404_with_dict(self):
r_body = '{"resp_body": {"err": "fake_resp_body"}}'
e = self.assertRaises(exceptions.NotFound,
self.rest_client._error_checker,
**self.set_data("404", r_body=r_body))
if self.c_type == 'application/json':
expected = {"err": "fake_resp_body"}
else:
expected = r_body
self.assertEqual(expected, e.resp_body)
def test_response_404_with_invalid_dict(self):
r_body = '{"foo": "bar"]'
e = self.assertRaises(exceptions.NotFound,
self.rest_client._error_checker,
**self.set_data("404", r_body=r_body))
expected = r_body
self.assertEqual(expected, e.resp_body)
def test_response_409_with_dict(self):
r_body = '{"resp_body": {"err": "fake_resp_body"}}'
e = self.assertRaises(exceptions.Conflict,
self.rest_client._error_checker,
**self.set_data("409", r_body=r_body))
if self.c_type == 'application/json':
expected = {"err": "fake_resp_body"}
else:
expected = r_body
self.assertEqual(expected, e.resp_body)
def test_response_500_with_dict(self):
r_body = '{"resp_body": {"err": "fake_resp_body"}}'
self.assertRaises(exceptions.ServerFault,
self.rest_client._error_checker,
**self.set_data("500", r_body=r_body))
e = self.assertRaises(exceptions.ServerFault,
self.rest_client._error_checker,
**self.set_data("500", r_body=r_body))
if self.c_type == 'application/json':
expected = {"err": "fake_resp_body"}
else:
expected = r_body
self.assertEqual(expected, e.resp_body)
def test_response_501_with_dict(self):
r_body = '{"resp_body": {"err": "fake_resp_body"}}'