Mark unhandled errors in deferreds differently to regular errors.
This commit is contained in:
@@ -167,10 +167,10 @@ class AsynchronousDeferredRunTest(RunTest):
|
|||||||
successful = False
|
successful = False
|
||||||
# XXX: Maybe we could log creator & invoker here as well if
|
# XXX: Maybe we could log creator & invoker here as well if
|
||||||
# present.
|
# present.
|
||||||
# XXX: Is there anything flagging these as unhandled errors?
|
|
||||||
for debug_info in unhandled:
|
for debug_info in unhandled:
|
||||||
f = debug_info.failResult
|
f = debug_info.failResult
|
||||||
self._got_user_exception((f.type, f.value, f.tb))
|
self._got_user_exception(
|
||||||
|
(f.type, f.value, f.tb), 'unhandled-error-in-deferred')
|
||||||
junk = spinner.clear_junk()
|
junk = spinner.clear_junk()
|
||||||
if junk:
|
if junk:
|
||||||
successful = False
|
successful = False
|
||||||
|
|||||||
@@ -146,11 +146,16 @@ class RunTest(object):
|
|||||||
except:
|
except:
|
||||||
return self._got_user_exception(sys.exc_info())
|
return self._got_user_exception(sys.exc_info())
|
||||||
|
|
||||||
def _got_user_exception(self, exc_info):
|
def _got_user_exception(self, exc_info, tb_label='traceback'):
|
||||||
"""Called when user code raises an exception."""
|
"""Called when user code raises an exception.
|
||||||
|
|
||||||
|
:param exc_info: A sys.exc_info() tuple for the user error.
|
||||||
|
:param tb_label: An optional string label for the error. If
|
||||||
|
not specified, will default to 'traceback'.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
e = exc_info[1]
|
e = exc_info[1]
|
||||||
self.case.onException(exc_info)
|
self.case.onException(exc_info, tb_label=tb_label)
|
||||||
finally:
|
finally:
|
||||||
del exc_info
|
del exc_info
|
||||||
for exc_class, handler in self.handlers:
|
for exc_class, handler in self.handlers:
|
||||||
|
|||||||
@@ -120,7 +120,9 @@ class TestCase(unittest.TestCase):
|
|||||||
unittest.TestCase.__init__(self, *args, **kwargs)
|
unittest.TestCase.__init__(self, *args, **kwargs)
|
||||||
self._cleanups = []
|
self._cleanups = []
|
||||||
self._unique_id_gen = itertools.count(1)
|
self._unique_id_gen = itertools.count(1)
|
||||||
self._traceback_id_gen = itertools.count(0)
|
# Generators to ensure unique traceback ids. Maps traceback label to
|
||||||
|
# iterators.
|
||||||
|
self._traceback_id_gens = {}
|
||||||
self.__setup_called = False
|
self.__setup_called = False
|
||||||
self.__teardown_called = False
|
self.__teardown_called = False
|
||||||
# __details is lazy-initialized so that a constructed-but-not-run
|
# __details is lazy-initialized so that a constructed-but-not-run
|
||||||
@@ -429,14 +431,14 @@ class TestCase(unittest.TestCase):
|
|||||||
prefix = self.id()
|
prefix = self.id()
|
||||||
return '%s-%d' % (prefix, self.getUniqueInteger())
|
return '%s-%d' % (prefix, self.getUniqueInteger())
|
||||||
|
|
||||||
def onException(self, exc_info):
|
def onException(self, exc_info, tb_label='traceback'):
|
||||||
"""Called when an exception propogates from test code.
|
"""Called when an exception propogates from test code.
|
||||||
|
|
||||||
:seealso addOnException:
|
:seealso addOnException:
|
||||||
"""
|
"""
|
||||||
if exc_info[0] not in [
|
if exc_info[0] not in [
|
||||||
TestSkipped, _UnexpectedSuccess, _ExpectedFailure]:
|
TestSkipped, _UnexpectedSuccess, _ExpectedFailure]:
|
||||||
self._report_traceback(exc_info)
|
self._report_traceback(exc_info, tb_label=tb_label)
|
||||||
for handler in self.__exception_handlers:
|
for handler in self.__exception_handlers:
|
||||||
handler(exc_info)
|
handler(exc_info)
|
||||||
|
|
||||||
@@ -461,12 +463,12 @@ class TestCase(unittest.TestCase):
|
|||||||
self._add_reason(reason)
|
self._add_reason(reason)
|
||||||
result.addSkip(self, details=self.getDetails())
|
result.addSkip(self, details=self.getDetails())
|
||||||
|
|
||||||
def _report_traceback(self, exc_info):
|
def _report_traceback(self, exc_info, tb_label='traceback'):
|
||||||
tb_id = advance_iterator(self._traceback_id_gen)
|
id_gen = self._traceback_id_gens.setdefault(
|
||||||
|
tb_label, itertools.count(0))
|
||||||
|
tb_id = advance_iterator(id_gen)
|
||||||
if tb_id:
|
if tb_id:
|
||||||
tb_label = 'traceback-%d' % tb_id
|
tb_label = '%s-%d' % (tb_label, tb_id)
|
||||||
else:
|
|
||||||
tb_label = 'traceback'
|
|
||||||
self.addDetail(tb_label, content.TracebackContent(exc_info, self))
|
self.addDetail(tb_label, content.TracebackContent(exc_info, self))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
@@ -345,7 +345,10 @@ class TestAsynchronousDeferredRunTest(TestCase):
|
|||||||
('addError', test, None),
|
('addError', test, None),
|
||||||
('stopTest', test)]))
|
('stopTest', test)]))
|
||||||
self.assertThat(
|
self.assertThat(
|
||||||
list(error.keys()), Equals(['traceback', 'traceback-1']))
|
list(error.keys()), Equals([
|
||||||
|
'unhandled-error-in-deferred',
|
||||||
|
'unhandled-error-in-deferred-1',
|
||||||
|
]))
|
||||||
|
|
||||||
def test_keyboard_interrupt_stops_test_run(self):
|
def test_keyboard_interrupt_stops_test_run(self):
|
||||||
# If we get a SIGINT during a test run, the test stops and no more
|
# If we get a SIGINT during a test run, the test stops and no more
|
||||||
@@ -438,7 +441,7 @@ class TestAsynchronousDeferredRunTest(TestCase):
|
|||||||
'traceback',
|
'traceback',
|
||||||
'traceback-1',
|
'traceback-1',
|
||||||
'traceback-2',
|
'traceback-2',
|
||||||
'traceback-3',
|
'unhandled-error-in-deferred',
|
||||||
]))
|
]))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user