Add informative error message for 404 responses

When the nsx backend returns 404 not found with error code 202,
the error message includes the exact resource that is missing.
Adding this information to the exception can help the customer to
understand the problem.

Change-Id: I5b34235ff56eb87b430c974ca43a696b6e505d0c
This commit is contained in:
Adit Sarfaty 2017-05-08 10:13:58 +03:00
parent b1dcc41cff
commit 8b39d9f6be
4 changed files with 36 additions and 10 deletions

View File

@ -67,7 +67,7 @@ class NsxV3ClientCertificateTestCase(nsxlib_testcase.NsxClientTestCase):
jsonutils.dumps({'httpStatus': 'go away',
'error_code': error_code,
'module_name': 'never mind',
'error message': 'bad luck'}))
'error_message': 'bad luck'}))
def _get_mocked_trust(self, action, cert_pem):

View File

@ -14,6 +14,7 @@
# under the License.
#
import copy
import requests
from oslo_log import log
from oslo_serialization import jsonutils
@ -228,9 +229,15 @@ class NsxV3RESTClientTestCase(nsxlib_testcase.NsxClientTestCase):
def test_client_validate_result(self):
def _verb_response_code(http_verb, status_code):
def _verb_response_code(http_verb, status_code, error_code=None):
content = None
if error_code:
content = jsonutils.dumps({'httpStatus': 'dummy',
'error_code': error_code,
'module_name': 'dummy',
'error_message': 'bad'})
response = mocks.MockRequestsResponse(
status_code, None)
status_code, content)
client_api = self.new_mocked_client(
client.RESTClient, mock_validate=False,
@ -244,7 +251,16 @@ class NsxV3RESTClientTestCase(nsxlib_testcase.NsxClientTestCase):
_verb_response_code(verb, code)
self.assertRaises(
nsxlib_exc.ManagerError,
_verb_response_code, verb, 500)
_verb_response_code, verb,
requests.codes.INTERNAL_SERVER_ERROR)
self.assertRaises(
nsxlib_exc.ResourceNotFound,
_verb_response_code, verb,
requests.codes.NOT_FOUND)
self.assertRaises(
nsxlib_exc.BackendResourceNotFound,
_verb_response_code, verb,
requests.codes.NOT_FOUND, 202)
class NsxV3JSONClientTestCase(nsxlib_testcase.NsxClientTestCase):

View File

@ -28,16 +28,21 @@ NULL_CURSOR_PREFIX = '0000'
def http_error_to_exception(status_code, error_code):
errors = {requests.codes.NOT_FOUND: exceptions.ResourceNotFound,
requests.codes.PRECONDITION_FAILED: exceptions.StaleRevision,
requests.codes.INTERNAL_SERVER_ERROR:
{'99': exceptions.ClientCertificateNotTrusted}}
errors = {
requests.codes.NOT_FOUND:
{'202': exceptions.BackendResourceNotFound,
'default': exceptions.ResourceNotFound},
requests.codes.PRECONDITION_FAILED: exceptions.StaleRevision,
requests.codes.INTERNAL_SERVER_ERROR:
{'99': exceptions.ClientCertificateNotTrusted}}
if status_code in errors:
if isinstance(errors[status_code], dict):
# choose based on error code
if error_code in errors[status_code]:
return errors[status_code][error_code]
if error_code and str(error_code) in errors[status_code]:
return errors[status_code][str(error_code)]
elif 'default' in errors[status_code]:
return errors[status_code]['default']
else:
return errors[status_code]

View File

@ -83,6 +83,11 @@ class ResourceNotFound(ManagerError):
"%(operation)s")
class BackendResourceNotFound(ResourceNotFound):
message = _("%(details)s On backend (%(manager)s) with Operation: "
"%(operation)s")
class InvalidInput(ManagerError):
message = _("%(operation)s failed: Invalid input %(arg_val)s "
"for %(arg_name)s")