diff options
author | David Cramer <dcramer@gmail.com> | 2016-08-11 11:33:03 -0700 |
---|---|---|
committer | David Cramer <dcramer@gmail.com> | 2016-08-11 11:36:04 -0700 |
commit | d71e27c4af796012a016eb5c576803016182dc66 (patch) | |
tree | d07df36fbc12a9ba0f657e54bbc3d4a5394aca62 | |
parent | c2be387c26b2069210d05fdc9aa6ccbf54abfe90 (diff) | |
download | raven-d71e27c4af796012a016eb5c576803016182dc66.tar.gz |
Prevent chained exception recursionfix/chain-recursion-2
Fixes GH-832
@getsentry/python
-rw-r--r-- | raven/events.py | 5 | ||||
-rw-r--r-- | tests/events/tests.py | 31 |
2 files changed, 36 insertions, 0 deletions
diff --git a/raven/events.py b/raven/events.py index 67402be..7434fe9 100644 --- a/raven/events.py +++ b/raven/events.py @@ -46,12 +46,17 @@ if hasattr(Exception, '__suppress_context__'): yield exc_info exc_type, exc, exc_traceback = exc_info + context = set() + context.add(exc) while True: if exc.__suppress_context__: # Then __cause__ should be used instead. exc = exc.__cause__ else: exc = exc.__context__ + if exc in context: + break + context.add(exc) if exc is None: break yield type(exc), exc, exc.__traceback__ diff --git a/tests/events/tests.py b/tests/events/tests.py index a75e326..e5795b4 100644 --- a/tests/events/tests.py +++ b/tests/events/tests.py @@ -1,3 +1,6 @@ +from __future__ import absolute_import + +import pytest import six from raven.base import Client @@ -67,3 +70,31 @@ class ExceptionTest(TestCase): six.raise_from(KeyError(), TypeError()) except Exception: self.check_capture(['KeyError', 'TypeError']) + + def test_handles_self_referencing(self): + try: + raise ValueError() + except Exception as exc: + try: + six.raise_from(exc, exc) + except Exception: + self.check_capture(['ValueError']) + else: + pytest.fail() + else: + pytest.fail() + + try: + raise ValueError() + except Exception as exc: + try: + six.raise_from(KeyError(), exc) + except KeyError as exc2: + try: + six.raise_from(exc, exc2) + except Exception: + self.check_capture(['ValueError', 'KeyError']) + else: + pytest.fail() + else: + pytest.fail() |