From 60eaa86892635098ff79d937343b64ffb509d925 Mon Sep 17 00:00:00 2001 From: Shawn Wang Date: Thu, 30 Jan 2020 13:10:29 -0800 Subject: [PATCH] Expose HTTP Status Code in ManagerError When ManagerError is raised due to unavailability of NSX backend, it is common that return HTTP status is non-200 and no error code is provided by NSX. In this case, recipient of ManagerError can hardly check the cause due to not having access to either error code or HTTP status code. This patch includes the HTTP status code in ManagerError, aiming to provide recipient a more reliable way to check the cause of error. Change-Id: Id346b27ad69ca4c3b3b4ef950a8c191ce46cde5e --- vmware_nsxlib/tests/unit/v3/test_client.py | 29 +++++++++++++--------- vmware_nsxlib/v3/client.py | 6 +++-- vmware_nsxlib/v3/exceptions.py | 1 + 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/vmware_nsxlib/tests/unit/v3/test_client.py b/vmware_nsxlib/tests/unit/v3/test_client.py index 20fcbbe3..c5111327 100644 --- a/vmware_nsxlib/tests/unit/v3/test_client.py +++ b/vmware_nsxlib/tests/unit/v3/test_client.py @@ -273,18 +273,16 @@ class NsxV3RESTClientTestCase(nsxlib_testcase.NsxClientTestCase): for verb in ['get', 'post', 'put', 'delete']: for code in client.RESTClient._VERB_RESP_CODES.get(verb): _verb_response_code(verb, code) - self.assertRaises( - nsxlib_exc.ManagerError, - _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) + with self.assertRaises(nsxlib_exc.ManagerError) as e: + _verb_response_code(verb, requests.codes.INTERNAL_SERVER_ERROR) + self.assertEqual(e.exception.status_code, + requests.codes.INTERNAL_SERVER_ERROR) + with self.assertRaises(nsxlib_exc.ResourceNotFound) as e: + _verb_response_code(verb, requests.codes.NOT_FOUND) + self.assertEqual(e.exception.status_code, requests.codes.NOT_FOUND) + with self.assertRaises(nsxlib_exc.BackendResourceNotFound) as e: + _verb_response_code(verb, requests.codes.NOT_FOUND, 202) + self.assertEqual(e.exception.status_code, requests.codes.NOT_FOUND) def test_inject_headers_callback(self): @@ -362,6 +360,13 @@ class NsxV3APIClientTestCase(nsxlib_testcase.NsxClientTestCase): 'get', api, 'https://1.2.3.4/api/v1/ports') + def test_raise_error(self): + api = self.new_mocked_client(client.NSX3Client) + with self.assertRaises(nsxlib_exc.ManagerError) as e: + api._raise_error(requests.codes.INTERNAL_SERVER_ERROR, 'GET', '') + self.assertEqual(e.exception.status_code, + requests.codes.INTERNAL_SERVER_ERROR) + # NOTE(boden): remove this when tmp brigding removed class NsxV3APIClientBridgeTestCase(nsxlib_testcase.NsxClientTestCase): diff --git a/vmware_nsxlib/v3/client.py b/vmware_nsxlib/v3/client.py index e1a1e05e..b3754cc4 100644 --- a/vmware_nsxlib/v3/client.py +++ b/vmware_nsxlib/v3/client.py @@ -153,7 +153,8 @@ class RESTClient(object): error = http_error_to_exception(status_code, error_code) raise error(manager='', operation=operation, details=result_msg, error_code=error_code, - related_error_codes=related_error_codes) + related_error_codes=related_error_codes, + status_code=status_code) def _validate_result(self, result, expected, operation, silent=False): if result.status_code not in expected: @@ -318,7 +319,8 @@ class NSX3Client(JSONRESTClient): operation=operation, details=result_msg, error_code=error_code, - related_error_codes=related_error_codes) + related_error_codes=related_error_codes, + status_code=status_code) def _rest_call(self, url, **kwargs): if kwargs.get('with_retries', True): diff --git a/vmware_nsxlib/v3/exceptions.py b/vmware_nsxlib/v3/exceptions.py index d66fc753..63cd46e9 100644 --- a/vmware_nsxlib/v3/exceptions.py +++ b/vmware_nsxlib/v3/exceptions.py @@ -86,6 +86,7 @@ class ManagerError(NsxLibException): self.msg = details self.error_code = kwargs.get('error_code') self.related_error_codes = kwargs.get('related_error_codes', []) + self.status_code = kwargs.get('status_code') class ResourceNotFound(ManagerError):