Fix ExtendedInfo error handling for non-list item
Conflicts: sushy/exceptions.py Change-Id: I2d082762fcf59d7b9bc8adc7c5159520ac628043 (cherry picked from commit7ec04224b4
) (cherry picked from commitdfe6b33fa6
)
This commit is contained in:
parent
74efff4083
commit
40df70a4ea
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixes ``AttributeError: 'str' object has no attribute 'get'`` during error
|
||||
handling. This occurs when BMC does not return a list of messages inside
|
||||
``@Message.ExtendedInfo``, but a single item. This has been observed with
|
||||
iDRAC.
|
|
@ -101,9 +101,9 @@ class HTTPError(SushyError):
|
|||
self.code = self.body.get('code', 'Base.1.0.GeneralError')
|
||||
self.detail = self.body.get('message')
|
||||
ext_info = self.body.get('@Message.ExtendedInfo', [{}])
|
||||
index = self._get_most_severe_msg_index(ext_info)
|
||||
self.detail = ext_info[index].get('Message', self.detail)
|
||||
error = '%s: %s' % (self.code, self.detail or 'unknown error')
|
||||
message = self._get_most_severe_msg(ext_info)
|
||||
self.detail = message or self.detail
|
||||
error = '%s: %s' % (self.code, self.detail or 'unknown error.')
|
||||
|
||||
kwargs = {'method': method, 'url': url, 'code': self.status_code,
|
||||
'error': error}
|
||||
|
@ -112,13 +112,14 @@ class HTTPError(SushyError):
|
|||
super(HTTPError, self).__init__(**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def _get_most_severe_msg_index(extended_info):
|
||||
def _get_most_severe_msg(extended_info):
|
||||
if not isinstance(extended_info, list):
|
||||
return extended_info.get('Message', None)
|
||||
if len(extended_info) > 0:
|
||||
for sev in ['Critical', 'Warning']:
|
||||
for i, m in enumerate(extended_info):
|
||||
if m.get('Severity') == sev:
|
||||
return i
|
||||
return 0
|
||||
return m.get('Message')
|
||||
|
||||
|
||||
class BadRequestError(HTTPError):
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"error": {
|
||||
"code": "Base.1.5.GeneralError",
|
||||
"message": "A general error has occurred. See ExtendedInfo for more information.",
|
||||
"@Message.ExtendedInfo": {
|
||||
"@odata.type": "#Message.v1_0_0.Message",
|
||||
"MessageId": "Base.1.5.GeneralError",
|
||||
"Message": "A general error has occurred. See Resolution for information on how to resolve the error.",
|
||||
"Resolution": "Redfish request contains unsupported media type. Correct the request body and resubmit.",
|
||||
"Severity": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -255,6 +255,21 @@ class ConnectorOpTestCase(base.TestCase):
|
|||
self.assertIsNotNone(exc.body)
|
||||
self.assertIn('body submitted was malformed JSON', exc.detail)
|
||||
|
||||
def test_known_http_error_nonlist_ext_info(self):
|
||||
self.request.return_value.status_code =\
|
||||
http_client.UNSUPPORTED_MEDIA_TYPE
|
||||
with open('sushy/tests/unit/json_samples/'
|
||||
'error_single_ext_info.json') as f:
|
||||
self.request.return_value.json.return_value = json.load(f)
|
||||
|
||||
with self.assertRaisesRegex(exceptions.HTTPError,
|
||||
'See Resolution for information') as cm:
|
||||
self.conn._op('POST', 'http://foo.bar')
|
||||
exc = cm.exception
|
||||
self.assertEqual(http_client.UNSUPPORTED_MEDIA_TYPE, exc.status_code)
|
||||
self.assertIsNotNone(exc.body)
|
||||
self.assertIn('See Resolution for information', exc.detail)
|
||||
|
||||
def test_not_found_error(self):
|
||||
self.request.return_value.status_code = http_client.NOT_FOUND
|
||||
self.request.return_value.json.side_effect = ValueError('no json')
|
||||
|
|
Loading…
Reference in New Issue