Do not hide unexpected exceptions in inspection code

We have to at least provide a traceback for Python stdlib exceptions.
Also provide a more meaningful error message to a user in last_error.

Related-Bug: #1550328
Change-Id: I7cbb4bc36b5524c902b587f68212439e8f2d45df
This commit is contained in:
Dmitry Tantsur 2016-10-12 16:58:32 +02:00
parent fd089b0a01
commit 340a5fab93
3 changed files with 36 additions and 8 deletions

View File

@ -2572,19 +2572,23 @@ def _do_inspect_hardware(task):
"""
node = task.node
def handle_failure(e):
def handle_failure(e, log_func=LOG.error):
node.last_error = e
task.process_event('fail')
LOG.error(_LE("Failed to inspect node %(node)s: %(err)s"),
{'node': node.uuid, 'err': e})
log_func(_LE("Failed to inspect node %(node)s: %(err)s"),
{'node': node.uuid, 'err': e})
try:
new_state = task.driver.inspect.inspect_hardware(task)
except Exception as e:
except exception.IronicException as e:
with excutils.save_and_reraise_exception():
error = str(e)
handle_failure(error)
except Exception as e:
error = (_('Unexpected exception of type %(type)s: %(msg)s') %
{'type': type(e).__name__, 'msg': e})
handle_failure(error, log_func=LOG.exception)
raise exception.HardwareInspectionFailure(error=error)
if new_state == states.MANAGEABLE:
task.process_event('done')

View File

@ -4512,12 +4512,32 @@ class NodeInspectHardware(mgr_utils.ServiceSetUpMixin,
target_provision_state=state)
task = task_manager.TaskManager(self.context, node.uuid)
self.assertRaises(exception.HardwareInspectionFailure,
manager._do_inspect_hardware, task)
self.assertRaisesRegex(exception.HardwareInspectionFailure, '^test$',
manager._do_inspect_hardware, task)
node.refresh()
self.assertEqual(states.INSPECTFAIL, node.provision_state)
self.assertEqual(states.MANAGEABLE, node.target_provision_state)
self.assertIsNotNone(node.last_error)
self.assertEqual('test', node.last_error)
self.assertTrue(mock_inspect.called)
@mock.patch('ironic.drivers.modules.fake.FakeInspect.inspect_hardware')
def test_inspect_hardware_unexpected_error(self, mock_inspect):
self._start_service()
mock_inspect.side_effect = RuntimeError('x')
state = states.MANAGEABLE
node = obj_utils.create_test_node(self.context, driver='fake',
provision_state=states.INSPECTING,
target_provision_state=state)
task = task_manager.TaskManager(self.context, node.uuid)
self.assertRaisesRegex(exception.HardwareInspectionFailure,
'Unexpected exception of type RuntimeError: x',
manager._do_inspect_hardware, task)
node.refresh()
self.assertEqual(states.INSPECTFAIL, node.provision_state)
self.assertEqual(states.MANAGEABLE, node.target_provision_state)
self.assertEqual('Unexpected exception of type RuntimeError: x',
node.last_error)
self.assertTrue(mock_inspect.called)

View File

@ -0,0 +1,4 @@
---
fixes:
- Correctly handle unexpected exceptions during inspection. Return more
detailed error message to a user and log the traceback.