Merge "Add a pformat() failure method and use it in the conductor"
This commit is contained in:
@@ -96,17 +96,24 @@ class SingleThreadedConductor(base.Conductor):
|
|||||||
engine.run()
|
engine.run()
|
||||||
except excp.WrappedFailure as e:
|
except excp.WrappedFailure as e:
|
||||||
if all((f.check(*NO_CONSUME_EXCEPTIONS) for f in e)):
|
if all((f.check(*NO_CONSUME_EXCEPTIONS) for f in e)):
|
||||||
LOG.warn("Job execution failed (consumption being"
|
|
||||||
" skipped): %s", job, exc_info=True)
|
|
||||||
consume = False
|
consume = False
|
||||||
else:
|
if LOG.isEnabledFor(logging.WARNING):
|
||||||
LOG.warn("Job execution failed: %s", job, exc_info=True)
|
if consume:
|
||||||
|
LOG.warn("Job execution failed (consumption being"
|
||||||
|
" skipped): %s [%s failures]", job, len(e))
|
||||||
|
else:
|
||||||
|
LOG.warn("Job execution failed (consumption"
|
||||||
|
" proceeding): %s [%s failures]", job, len(e))
|
||||||
|
# Show the failure/s + traceback (if possible)...
|
||||||
|
for i, f in enumerate(e):
|
||||||
|
LOG.warn("%s. %s", i + 1, f.pformat(traceback=True))
|
||||||
except NO_CONSUME_EXCEPTIONS:
|
except NO_CONSUME_EXCEPTIONS:
|
||||||
LOG.warn("Job execution failed (consumption being"
|
LOG.warn("Job execution failed (consumption being"
|
||||||
" skipped): %s", job, exc_info=True)
|
" skipped): %s", job, exc_info=True)
|
||||||
consume = False
|
consume = False
|
||||||
except Exception:
|
except Exception:
|
||||||
LOG.warn("Job execution failed: %s", job, exc_info=True)
|
LOG.warn("Job execution failed (consumption proceeding): %s",
|
||||||
|
job, exc_info=True)
|
||||||
else:
|
else:
|
||||||
LOG.info("Job completed successfully: %s", job)
|
LOG.info("Job completed successfully: %s", job)
|
||||||
return consume
|
return consume
|
||||||
|
@@ -42,6 +42,10 @@ class GeneralFailureObjTestsMixin(object):
|
|||||||
self.assertEqual(list(self.fail_obj),
|
self.assertEqual(list(self.fail_obj),
|
||||||
test_utils.RUNTIME_ERROR_CLASSES[:-2])
|
test_utils.RUNTIME_ERROR_CLASSES[:-2])
|
||||||
|
|
||||||
|
def test_pformat_no_traceback(self):
|
||||||
|
text = self.fail_obj.pformat()
|
||||||
|
self.assertNotIn("Traceback", text)
|
||||||
|
|
||||||
def test_check_str(self):
|
def test_check_str(self):
|
||||||
val = 'Exception'
|
val = 'Exception'
|
||||||
self.assertEqual(self.fail_obj.check(val), val)
|
self.assertEqual(self.fail_obj.check(val), val)
|
||||||
@@ -91,6 +95,10 @@ class ReCreatedFailureTestCase(test.TestCase, GeneralFailureObjTestsMixin):
|
|||||||
def test_no_exc_info(self):
|
def test_no_exc_info(self):
|
||||||
self.assertIs(self.fail_obj.exc_info, None)
|
self.assertIs(self.fail_obj.exc_info, None)
|
||||||
|
|
||||||
|
def test_pformat_traceback(self):
|
||||||
|
text = self.fail_obj.pformat(traceback=True)
|
||||||
|
self.assertIn("Traceback (most recent call last):", text)
|
||||||
|
|
||||||
def test_reraises(self):
|
def test_reraises(self):
|
||||||
exc = self.assertRaises(exceptions.WrappedFailure,
|
exc = self.assertRaises(exceptions.WrappedFailure,
|
||||||
self.fail_obj.reraise)
|
self.fail_obj.reraise)
|
||||||
@@ -103,6 +111,10 @@ class FromExceptionTestCase(test.TestCase, GeneralFailureObjTestsMixin):
|
|||||||
super(FromExceptionTestCase, self).setUp()
|
super(FromExceptionTestCase, self).setUp()
|
||||||
self.fail_obj = misc.Failure.from_exception(RuntimeError('Woot!'))
|
self.fail_obj = misc.Failure.from_exception(RuntimeError('Woot!'))
|
||||||
|
|
||||||
|
def test_pformat_no_traceback(self):
|
||||||
|
text = self.fail_obj.pformat(traceback=True)
|
||||||
|
self.assertIn("Traceback not available", text)
|
||||||
|
|
||||||
|
|
||||||
class FailureObjectTestCase(test.TestCase):
|
class FailureObjectTestCase(test.TestCase):
|
||||||
|
|
||||||
@@ -188,6 +200,17 @@ class FailureObjectTestCase(test.TestCase):
|
|||||||
self.assertNotEqual(captured, None)
|
self.assertNotEqual(captured, None)
|
||||||
self.assertFalse(captured.matches(None))
|
self.assertFalse(captured.matches(None))
|
||||||
|
|
||||||
|
def test_pformat_traceback(self):
|
||||||
|
captured = _captured_failure('Woot!')
|
||||||
|
text = captured.pformat(traceback=True)
|
||||||
|
self.assertIn("Traceback (most recent call last):", text)
|
||||||
|
|
||||||
|
def test_pformat_traceback_captured_no_exc_info(self):
|
||||||
|
captured = _captured_failure('Woot!')
|
||||||
|
captured = misc.Failure.from_dict(captured.to_dict())
|
||||||
|
text = captured.pformat(traceback=True)
|
||||||
|
self.assertIn("Traceback (most recent call last):", text)
|
||||||
|
|
||||||
|
|
||||||
class WrappedFailureTestCase(test.TestCase):
|
class WrappedFailureTestCase(test.TestCase):
|
||||||
|
|
||||||
|
@@ -696,8 +696,23 @@ class Failure(object):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Failure: %s: %s' % (self._exc_type_names[0],
|
return self.pformat()
|
||||||
self._exception_str)
|
|
||||||
|
def pformat(self, traceback=False):
|
||||||
|
buf = six.StringIO()
|
||||||
|
buf.write(
|
||||||
|
'Failure: %s: %s' % (self._exc_type_names[0], self._exception_str))
|
||||||
|
if traceback:
|
||||||
|
if self._traceback_str is not None:
|
||||||
|
traceback_str = self._traceback_str.rstrip()
|
||||||
|
else:
|
||||||
|
traceback_str = None
|
||||||
|
if traceback_str:
|
||||||
|
buf.write('\nTraceback (most recent call last):\n')
|
||||||
|
buf.write(traceback_str)
|
||||||
|
else:
|
||||||
|
buf.write('\nTraceback not available.')
|
||||||
|
return buf.getvalue()
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"""Iterate over exception type names."""
|
"""Iterate over exception type names."""
|
||||||
|
Reference in New Issue
Block a user