Merge "Print human friendly string as an error message"
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user