diff options
author | David Cramer <dcramer@gmail.com> | 2017-03-05 19:12:53 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-05 19:12:53 -0800 |
commit | 6f0727c50ff436074b985ad01490eda6b6efa9a5 (patch) | |
tree | 6989a6497699477221e57a46f4505ae887c9822a | |
parent | 7c5b42710153622a7a774a3e85c7d002f1c8075f (diff) | |
parent | 271d1aa797704fef94b83f5f03b96ad0d9d7200d (diff) | |
download | raven-6f0727c50ff436074b985ad01490eda6b6efa9a5.tar.gz |
Merge pull request #964 from noirbizarre/gh-963-handle-exception-inheritance
Handle ignore_exceptions values being class or string
-rw-r--r-- | CHANGES | 2 | ||||
-rw-r--r-- | docs/advanced.rst | 5 | ||||
-rw-r--r-- | raven/base.py | 15 | ||||
-rw-r--r-- | raven/contrib/flask.py | 5 | ||||
-rw-r--r-- | tests/base/tests.py | 39 |
5 files changed, 60 insertions, 6 deletions
@@ -13,6 +13,8 @@ Version 6.0.0 affected things like django-tastyepie. * Corrected an issue where Django's HTTP request was not always available within events. +* Support both string and class values for ``ignore_exceptions`` parameters. + Class values also support child exceptions. Version 5.32.0 -------------- diff --git a/docs/advanced.rst b/docs/advanced.rst index 851d528..dc6f042 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -168,8 +168,13 @@ The following are valid arguments which may be passed to the Raven client: 'Http404', 'django.exceptions.http.Http404', 'django.exceptions.*', + ValueError, ] + Each item can be either a string or a class. + String declaration is strict (ie. does not works for child exceptions) + whereas class declaration handle inheritance (ie. child exceptions are also ignored). + .. describe:: list_max_length The maximum number of items a list-like container should store. diff --git a/raven/base.py b/raven/base.py index 7924d8b..c38f042 100644 --- a/raven/base.py +++ b/raven/base.py @@ -17,6 +17,7 @@ import uuid import warnings from datetime import datetime +from inspect import isclass from types import FunctionType from threading import local @@ -60,6 +61,9 @@ SDK_VALUE = { # singleton for the client Raven = None +if sys.version_info >= (3, 2): + basestring = str + def get_excepthook_client(): hook = sys.excepthook @@ -802,12 +806,19 @@ class Client(object): exc_type = exc_info[0] exc_name = '%s.%s' % (exc_type.__module__, exc_type.__name__) exclusions = self.ignore_exceptions + string_exclusions = (e for e in exclusions if isinstance(e, basestring)) + wildcard_exclusions = (e for e in string_exclusions if e.endswith('*')) + class_exclusions = (e for e in exclusions if isclass(e)) - if exc_type.__name__ in exclusions: + if exc_type in exclusions: + return False + elif exc_type.__name__ in exclusions: return False elif exc_name in exclusions: return False - elif any(exc_name.startswith(e[:-1]) for e in exclusions if e.endswith('*')): + elif any(issubclass(exc_type, e) for e in class_exclusions): + return False + elif any(exc_name.startswith(e[:-1]) for e in wildcard_exclusions): return False return True diff --git a/raven/contrib/flask.py b/raven/contrib/flask.py index a13b838..b8ac494 100644 --- a/raven/contrib/flask.py +++ b/raven/contrib/flask.py @@ -42,10 +42,7 @@ def make_client(client_cls, app, dsn=None): | set([app.import_name]) ), # support legacy RAVEN_IGNORE_EXCEPTIONS - 'ignore_exceptions': [ - '{0}.{1}'.format(x.__module__, x.__name__) - for x in app.config.get('RAVEN_IGNORE_EXCEPTIONS', []) - ], + 'ignore_exceptions': app.config.get('RAVEN_IGNORE_EXCEPTIONS', []), 'extra': { 'app': app, }, diff --git a/tests/base/tests.py b/tests/base/tests.py index 040f3bd..736cf1c 100644 --- a/tests/base/tests.py +++ b/tests/base/tests.py @@ -325,6 +325,45 @@ class ClientTest(TestCase): self.assertEquals(frame['filename'], 'tests/base/tests.py') self.assertEquals(frame['module'], __name__) + def test_exception_event_ignore_string(self): + class Foo(Exception): + pass + + client = TempStoreClient(ignore_exceptions=['Foo']) + try: + raise Foo() + except Foo: + client.captureException() + + self.assertEquals(len(client.events), 0) + + def test_exception_event_ignore_class(self): + class Foo(Exception): + pass + + client = TempStoreClient(ignore_exceptions=[Foo]) + try: + raise Foo() + except Foo: + client.captureException() + + self.assertEquals(len(client.events), 0) + + def test_exception_event_ignore_child(self): + class Foo(Exception): + pass + + class Bar(Foo): + pass + + client = TempStoreClient(ignore_exceptions=[Foo]) + try: + raise Bar() + except Bar: + client.captureException() + + self.assertEquals(len(client.events), 0) + def test_decorator_preserves_function(self): @self.client.capture_exceptions def test1(): |