summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrian Sutherland <brian@vanguardistas.net>2011-07-20 16:51:22 +0000
committerBrian Sutherland <brian@vanguardistas.net>2011-07-20 16:51:22 +0000
commit1404e18df1bd4db82dc89dadbdfd9354a4cc000b (patch)
tree9116974f1153bb5880e17c7da792e6e54459e8df /src
parent63a4931229e2a14b0a175ff363de92d6e27cefa4 (diff)
downloadzope-exceptions-1404e18df1bd4db82dc89dadbdfd9354a4cc000b.tar.gz
Fallback to traceback.format_tb when the formatter is called recursively.
i.e. Don't let errors in the formatter pass silently. This patch saves lots of hair pulling with doctest encoding issues under zope.testrunner.
Diffstat (limited to 'src')
-rw-r--r--src/zope/exceptions/exceptionformatter.py3
-rw-r--r--src/zope/exceptions/tests/test_exceptionformatter.py23
2 files changed, 25 insertions, 1 deletions
diff --git a/src/zope/exceptions/exceptionformatter.py b/src/zope/exceptions/exceptionformatter.py
index 7fdbd69..407032c 100644
--- a/src/zope/exceptions/exceptionformatter.py
+++ b/src/zope/exceptions/exceptionformatter.py
@@ -171,7 +171,8 @@ class TextExceptionFormatter(object):
while tb is not None and (limit is None or n < limit):
if tb.tb_frame.f_locals.get('__exception_formatter__'):
# Stop recursion.
- result.append('(Recursive formatException() stopped)\n')
+ result.append('(Recursive formatException() stopped, trying traceback.format_tb)\n')
+ result.extend(traceback.format_tb(tb))
break
line = self.formatLine(tb)
result.append(line + '\n')
diff --git a/src/zope/exceptions/tests/test_exceptionformatter.py b/src/zope/exceptions/tests/test_exceptionformatter.py
index 1243141..c4d139c 100644
--- a/src/zope/exceptions/tests/test_exceptionformatter.py
+++ b/src/zope/exceptions/tests/test_exceptionformatter.py
@@ -152,6 +152,29 @@ class Test(TestCase):
' ^',
'SyntaxError: invalid syntax'])
+ def testRecursionFailure(self):
+ from zope.exceptions.exceptionformatter import TextExceptionFormatter
+
+ class FormatterException(Exception):
+ pass
+
+ class FailingFormatter(TextExceptionFormatter):
+ def formatLine(self, tb):
+ raise FormatterException("Formatter failed")
+
+ fmt = FailingFormatter()
+ try:
+ raise ExceptionForTesting
+ except ExceptionForTesting:
+ try:
+ fmt.formatException(*sys.exc_info())
+ except FormatterException:
+ s = tb()
+ # Recursion was detected
+ self.assertTrue('(Recursive formatException() stopped, trying traceback.format_tb)' in s, s)
+ # and we fellback to the stdlib rather than hid the real error
+ self.assertEquals(s.splitlines()[-2], ' raise FormatterException("Formatter failed")')
+ self.assertTrue('FormatterException: Formatter failed' in s.splitlines()[-1])
def test_suite():
return makeSuite(Test)