diff options
| author | Brian Sutherland <brian@vanguardistas.net> | 2011-07-20 16:51:22 +0000 |
|---|---|---|
| committer | Brian Sutherland <brian@vanguardistas.net> | 2011-07-20 16:51:22 +0000 |
| commit | 1404e18df1bd4db82dc89dadbdfd9354a4cc000b (patch) | |
| tree | 9116974f1153bb5880e17c7da792e6e54459e8df /src | |
| parent | 63a4931229e2a14b0a175ff363de92d6e27cefa4 (diff) | |
| download | zope-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.py | 3 | ||||
| -rw-r--r-- | src/zope/exceptions/tests/test_exceptionformatter.py | 23 |
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) |
