diff --git a/ironic_inspector_client/common/http.py b/ironic_inspector_client/common/http.py index 5a12b45..a8108d0 100644 --- a/ironic_inspector_client/common/http.py +++ b/ironic_inspector_client/common/http.py @@ -47,12 +47,31 @@ class ClientError(requests.HTTPError): # inspector returns error message in body msg = response.content.decode(_ERROR_ENCODING) try: - msg = json.loads(msg)['error']['message'] + msg = json.loads(msg) except ValueError: LOG.debug('Old style error response returned, assuming ' 'ironic-discoverd') - except (KeyError, TypeError): + except TypeError: LOG.exception('Bad error response from Ironic Inspector') + else: + try: + msg = msg['error']['message'] + except KeyError as exc: + LOG.error('Invalid error response from Ironic Inspector: ' + '%(msg)s (missing key %(key)s)', + {'msg': msg, 'key': exc}) + # It's surprisingly common to try accessing ironic URL with + # ironic-inspector-client, handle this case + try: + msg = msg['error_message'] + except KeyError: + pass + else: + msg = _('Received Ironic-style response %s. Are you ' + 'trying to access Ironic URL instead of Ironic ' + 'Inspector?') % msg + except TypeError: + LOG.exception('Bad error response from Ironic Inspector') LOG.debug('Inspector returned error "%(msg)s" (HTTP %(code)s)', {'msg': msg, 'code': response.status_code}) diff --git a/ironic_inspector_client/test/test_common_http.py b/ironic_inspector_client/test/test_common_http.py index 4199fea..0e2ac02 100644 --- a/ironic_inspector_client/test/test_common_http.py +++ b/ironic_inspector_client/test/test_common_http.py @@ -192,3 +192,28 @@ class TestRequest(unittest.TestCase): self.assertRaisesRegex(http.ClientError, 'boom', self.get_client().request, 'get', 'url') + + def test_accessing_ironic(self): + self.req.return_value.status_code = 400 + self.req.return_value.content = json.dumps( + {"error_message": "{\"code\": 404, \"title\": \"Not Found\", " + "\"description\": \"\"}"}).encode('utf-8') + + self.assertRaisesRegex(http.ClientError, + 'Ironic-style response.*Not Found', + self.get_client().request, 'get', 'url') + + def test_error_non_sense(self): + self.req.return_value.status_code = 400 + self.req.return_value.content = json.dumps( + {'hello': 'world'}).encode('utf-8') + + self.assertRaisesRegex(http.ClientError, 'hello', + self.get_client().request, 'get', 'url') + + def test_error_non_sense2(self): + self.req.return_value.status_code = 400 + self.req.return_value.content = b'42' + + self.assertRaisesRegex(http.ClientError, '42', + self.get_client().request, 'get', 'url') diff --git a/releasenotes/notes/ironic-error-657d352b31ba77ed.yaml b/releasenotes/notes/ironic-error-657d352b31ba77ed.yaml new file mode 100644 index 0000000..6e30a58 --- /dev/null +++ b/releasenotes/notes/ironic-error-657d352b31ba77ed.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Provides a clear error message when trying to access an ironic URL with + ironic-inspector-client.