From a03cec98da6fd77bd73e783c2b6c95033bd1b239 Mon Sep 17 00:00:00 2001 From: Boden R Date: Thu, 22 Oct 2015 09:52:29 -0600 Subject: [PATCH] NSX v3 API client error propagation Currently the NSX v3 REST API client masks the backend NSX API error upon and invalid response. This results in a very generic error message to consumers (including the CLI) when a backend error happens. This patch exposes the backend error message if possible which provides more details of the issue to consumers. Change-Id: I215352d649b6579d6075cb104a7d311a7f1ffa66 --- vmware_nsx/common/exceptions.py | 8 +++++++- vmware_nsx/nsxlib/v3/client.py | 10 ++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/vmware_nsx/common/exceptions.py b/vmware_nsx/common/exceptions.py index 85ecea48d0..be39f76548 100644 --- a/vmware_nsx/common/exceptions.py +++ b/vmware_nsx/common/exceptions.py @@ -127,7 +127,13 @@ class NoRouterAvailable(n_exc.ResourceExhausted): class ManagerError(NsxPluginException): message = _("Unexpected error from backend manager (%(manager)s) " - "for %(operation)s") + "for %(operation)s %(details)s") + + def __init__(self, **kwargs): + kwargs['details'] = (': %s' % kwargs['details'] + if 'details' in kwargs + else '') + super(ManagerError, self).__init__(**kwargs) class ResourceNotFound(ManagerError): diff --git a/vmware_nsx/nsxlib/v3/client.py b/vmware_nsx/nsxlib/v3/client.py index caa122c2f8..adf22fd6a3 100644 --- a/vmware_nsx/nsxlib/v3/client.py +++ b/vmware_nsx/nsxlib/v3/client.py @@ -101,17 +101,23 @@ class RESTClient(object): def _validate_result(self, result, expected, operation): if result.status_code not in expected: + result_msg = result.json() if result.content else '' LOG.warning(_LW("The HTTP request returned error code " "%(result)d, whereas %(expected)s response " "codes were expected. Response body %(body)s"), {'result': result.status_code, 'expected': '/'.join([str(code) for code in expected]), - 'body': result.json() if result.content else ''}) + 'body': result_msg}) manager_error = ERRORS.get( result.status_code, nsx_exc.ManagerError) - raise manager_error(manager=self._host_ip, operation=operation) + if type(result_msg) is dict: + result_msg = result_msg.get('error_message', result_msg) + raise manager_error( + manager=self._host_ip, + operation=operation, + details=result_msg) @classmethod def merge_headers(cls, *headers):