Merge "Print human friendly string as an error message"

This commit is contained in:
Jenkins
2014-03-06 15:12:22 +00:00
committed by Gerrit Code Review
4 changed files with 121 additions and 33 deletions

View File

@@ -161,8 +161,6 @@ class HTTPClient(httplib2.Http):
status_code = self.get_status_code(resp)
if status_code == 401:
raise exceptions.Unauthorized(message=body)
elif status_code == 403:
raise exceptions.Forbidden(message=body)
return resp, body
def _strip_credentials(self, kwargs):

View File

@@ -528,13 +528,84 @@ class ClientV2UnicodeTestXML(ClientV2UnicodeTestJson):
class CLITestV20ExceptionHandler(CLITestV20Base):
def _test_exception_handler_v20(
self, expected_exception, status_code, expected_msg,
error_type=None, error_msg=None, error_detail=None,
error_content=None):
if error_content is None:
error_content = {'NeutronError': {'type': error_type,
'message': error_msg,
'detail': error_detail}}
e = self.assertRaises(expected_exception,
client.exception_handler_v20,
status_code, error_content)
self.assertEqual(status_code, e.status_code)
if expected_msg is None:
if error_detail:
expected_msg = '\n'.join([error_msg, error_detail])
else:
expected_msg = error_msg
self.assertEqual(expected_msg, e.message)
def test_exception_handler_v20_ip_address_in_use(self):
# Tests that an IpAddressInUse exception from the server is
# translated to an IpAddressInUseClient exception in the client.
err_msg = ('Unable to complete operation for network '
'fake-network-uuid. The IP address fake-ip is in use.')
err_data = {'type': 'IpAddressInUse', 'message': err_msg, 'detail': ''}
error_content = {'NeutronError': err_data}
self.assertRaises(exceptions.IpAddressInUseClient,
client.exception_handler_v20,
409, error_content)
self._test_exception_handler_v20(
exceptions.IpAddressInUseClient, 409, err_msg,
'IpAddressInUse', err_msg, '')
def test_exception_handler_v20_neutron_known_error(self):
error_msg = 'Network not found'
error_detail = 'Network detail'
self._test_exception_handler_v20(
exceptions.NetworkNotFoundClient, 404,
error_msg + '\n' + error_detail,
'NetworkNotFound', error_msg, error_detail)
def test_exception_handler_v20_neutron_known_error_without_detail(self):
error_msg = 'Network not found'
error_detail = ''
self._test_exception_handler_v20(
exceptions.NetworkNotFoundClient, 404,
error_msg,
'NetworkNotFound', error_msg, error_detail)
def test_exception_handler_v20_neutron_unknown_error(self):
error_msg = 'Unknown error'
error_detail = 'This is detail'
self._test_exception_handler_v20(
exceptions.NeutronClientException, 400,
error_msg + '\n' + error_detail,
'UnknownError', error_msg, error_detail)
def test_exception_handler_v20_bad_neutron_error(self):
error_content = {'NeutronError': {'unknown_key': 'UNKNOWN'}}
self._test_exception_handler_v20(
exceptions.NeutronClientException, 500,
expected_msg={'unknown_key': 'UNKNOWN'},
error_content=error_content)
def test_exception_handler_v20_error_dict_contains_message(self):
error_content = {'message': 'This is an error message'}
self._test_exception_handler_v20(
exceptions.NeutronClientException, 500,
expected_msg='This is an error message',
error_content=error_content)
def test_exception_handler_v20_error_dict_not_contain_message(self):
error_content = {'error': 'This is an error message'}
expected_msg = '%s-%s' % (500, error_content)
self._test_exception_handler_v20(
exceptions.NeutronClientException, 500,
expected_msg=expected_msg,
error_content=error_content)
def test_exception_handler_v20_default_fallback(self):
error_content = 'This is an error message'
expected_msg = '%s-%s' % (500, error_content)
self._test_exception_handler_v20(
exceptions.NeutronClientException, 500,
expected_msg=expected_msg,
error_content=error_content)

View File

@@ -61,3 +61,25 @@ class TestHTTPClient(testtools.TestCase):
self.assertEqual(rv_should_be, self.http._cs_request(URL, METHOD))
self.mox.VerifyAll()
def test_request_unauthorized(self):
rv_should_be = MyResp(401), 'unauthorized message'
httplib2.Http.request(
URL, METHOD, headers=mox.IgnoreArg()
).AndReturn(rv_should_be)
self.mox.ReplayAll()
e = self.assertRaises(exceptions.Unauthorized,
self.http._cs_request, URL, METHOD)
self.assertEqual('unauthorized message', e.message)
self.mox.VerifyAll()
def test_request_forbidden_is_returned_to_caller(self):
rv_should_be = MyResp(403), 'forbidden message'
httplib2.Http.request(
URL, METHOD, headers=mox.IgnoreArg()
).AndReturn(rv_should_be)
self.mox.ReplayAll()
self.assertEqual(rv_should_be, self.http._cs_request(URL, METHOD))
self.mox.VerifyAll()

View File

@@ -30,6 +30,18 @@ from neutronclient.common import utils
_logger = logging.getLogger(__name__)
NEUTRON_ERRORS = {
'NetworkNotFound': exceptions.NetworkNotFoundClient,
'NetworkInUse': exceptions.NetworkInUseClient,
'PortNotFound': exceptions.PortNotFoundClient,
'RequestedStateInvalid': exceptions.StateInvalidClient,
'PortInUse': exceptions.PortInUseClient,
'IpAddressInUse': exceptions.IpAddressInUseClient,
'AlreadyAttached': exceptions.AlreadyAttachedClient,
'IpAddressGenerationFailure': exceptions.IpAddressGenerationFailureClient,
'ExternalIpAddressExhausted': exceptions.ExternalIpAddressExhaustedClient,
}
def exception_handler_v20(status_code, error_content):
"""Exception handler for API v2.0 client
@@ -41,20 +53,6 @@ def exception_handler_v20(status_code, error_content):
:param status_code: HTTP error status code
:param error_content: deserialized body of error response
"""
neutron_errors = {
'NetworkNotFound': exceptions.NetworkNotFoundClient,
'NetworkInUse': exceptions.NetworkInUseClient,
'PortNotFound': exceptions.PortNotFoundClient,
'RequestedStateInvalid': exceptions.StateInvalidClient,
'PortInUse': exceptions.PortInUseClient,
'IpAddressInUse': exceptions.IpAddressInUseClient,
'AlreadyAttached': exceptions.AlreadyAttachedClient,
'IpAddressGenerationFailure':
exceptions.IpAddressGenerationFailureClient,
'ExternalIpAddressExhausted':
exceptions.ExternalIpAddressExhaustedClient, }
error_dict = None
if isinstance(error_content, dict):
error_dict = error_content.get('NeutronError')
@@ -65,27 +63,26 @@ def exception_handler_v20(status_code, error_content):
# a 'message' and 'type' keys?
try:
error_type = error_dict['type']
error_message = (error_dict['message'] + "\n" +
error_dict['detail'])
error_message = error_dict['message']
if error_dict['detail']:
error_message += "\n" + error_dict['detail']
except Exception:
bad_neutron_error_flag = True
if not bad_neutron_error_flag:
ex = None
try:
# raise the appropriate error!
ex = neutron_errors[error_type](message=error_message,
status_code=status_code)
except Exception:
pass
if ex:
raise ex
raise NEUTRON_ERRORS[error_type](message=error_message,
status_code=status_code)
except KeyError:
raise exceptions.NeutronClientException(
status_code=status_code, message=error_message)
else:
raise exceptions.NeutronClientException(status_code=status_code,
message=error_dict)
else:
message = None
if isinstance(error_content, dict):
message = error_content.get('message', None)
message = error_content.get('message')
if message:
raise exceptions.NeutronClientException(status_code=status_code,
message=message)