summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Cramer <dcramer@gmail.com>2016-07-22 10:54:36 -0700
committerDavid Cramer <dcramer@gmail.com>2016-07-22 10:58:55 -0700
commitca83d9ba70726c925049b3be27a48e37720d4d74 (patch)
treedde84d0b7529733b902333998761b0772c500dfb
parentc3e170312df8d5efd64d33a55b7f66496117a86e (diff)
downloadraven-feature/ignore-exceptions.tar.gz
Add ignore_exceptions to client configurationfeature/ignore-exceptions
This takes Django's IGNORE_EXCEPTIONS support and moves it into core. @getsentry/python
-rw-r--r--docs/advanced.rst10
-rw-r--r--raven/base.py22
-rw-r--r--raven/contrib/django/models.py12
-rw-r--r--tests/contrib/django/tests.py39
4 files changed, 53 insertions, 30 deletions
diff --git a/docs/advanced.rst b/docs/advanced.rst
index 77f940d..5a9749c 100644
--- a/docs/advanced.rst
+++ b/docs/advanced.rst
@@ -129,6 +129,16 @@ The following are valid arguments which may be passed to the Raven client:
'lxml.objectify',
]
+.. describe:: ignore_exceptions
+
+ A list of exceptions to ignore.
+
+ ignore_exceptions = [
+ 'Http404',
+ 'django.exceptions.http.Http404',
+ 'django.exceptions.*',
+ ]
+
.. describe:: max_list_length
The maximum number of items a list-like container should store.
diff --git a/raven/base.py b/raven/base.py
index bae7584..04d3b92 100644
--- a/raven/base.py
+++ b/raven/base.py
@@ -180,6 +180,8 @@ class Client(object):
self.environment = o.get('environment') or None
self.release = o.get('release') or os.environ.get('HEROKU_SLUG_COMMIT')
+ self.ignore_exceptions = set(o.get('ignore_exceptions') or ())
+
self.module_cache = ModuleProxyCache()
if not self.is_enabled():
@@ -764,9 +766,29 @@ class Client(object):
"""
if exc_info is None or exc_info is True:
exc_info = sys.exc_info()
+
+ if not self.should_capture(exc_info):
+ self.logger.info(
+ 'Not capturing exception due to filters: %s', exc_info[0],
+ exc_info=sys.exc_info())
+ return
+
return self.capture(
'raven.events.Exception', exc_info=exc_info, **kwargs)
+ def should_capture(self, exc_info):
+ exc_type = exc_info[0]
+ exc_name = '%s.%s' % (exc_type.__module__, exc_type.__name__)
+ exclusions = self.ignore_exceptions
+
+ if 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('*')):
+ return False
+ return True
+
def capture_exceptions(self, function_or_exceptions=None, **kwargs):
"""
Wrap a function or code block in try/except and automatically call
diff --git a/raven/contrib/django/models.py b/raven/contrib/django/models.py
index 490978a..bad6fc3 100644
--- a/raven/contrib/django/models.py
+++ b/raven/contrib/django/models.py
@@ -137,6 +137,7 @@ def get_client(client=None, reset=False):
options.setdefault('dsn', ga('DSN'))
options.setdefault('context', ga('CONTEXT'))
options.setdefault('release', ga('RELEASE'))
+ options.setdefault('ignore_exceptions', ga('IGNORE_EXCEPTIONS'))
transport = ga('TRANSPORT') or options.get('transport')
if isinstance(transport, string_types):
@@ -160,17 +161,6 @@ def get_client(client=None, reset=False):
def sentry_exception_handler(request=None, **kwargs):
- exc_type = sys.exc_info()[0]
-
- exclusions = set(get_option('IGNORE_EXCEPTIONS', ()))
-
- exc_name = '%s.%s' % (exc_type.__module__, exc_type.__name__)
- if exc_type.__name__ in exclusions or exc_name in exclusions or any(exc_name.startswith(e[:-1]) for e in exclusions if e.endswith('*')):
- logger.info(
- 'Not capturing exception due to filters: %s', exc_type,
- exc_info=sys.exc_info())
- return
-
try:
client.captureException(exc_info=sys.exc_info(), request=request)
except Exception as exc:
diff --git a/tests/contrib/django/tests.py b/tests/contrib/django/tests.py
index 8d96ec1..53bf09b 100644
--- a/tests/contrib/django/tests.py
+++ b/tests/contrib/django/tests.py
@@ -755,39 +755,40 @@ class SentryExceptionHandlerTest(TestCase):
captureException.assert_called_once_with(exc_info=self.exc_info, request=self.request)
- @mock.patch.object(TempStoreClient, 'captureException')
+ @mock.patch.object(TempStoreClient, 'capture')
@mock.patch('sys.exc_info')
- @mock.patch('raven.contrib.django.models.get_option')
- def test_does_exclude_filtered_types(self, get_option, exc_info, captureException):
+ def test_does_exclude_filtered_types(self, exc_info, mock_capture):
exc_info.return_value = self.exc_info
- get_option.return_value = ['ValueError']
+ get_client().ignore_exceptions = set(['ValueError'])
sentry_exception_handler(request=self.request)
- assert not captureException.called
+ assert not mock_capture.called
- @mock.patch.object(TempStoreClient, 'captureException')
+ @mock.patch.object(TempStoreClient, 'capture')
@mock.patch('sys.exc_info')
- @mock.patch('raven.contrib.django.models.get_option')
- def test_ignore_exceptions_with_expression_match(self, get_option, exc_info, captureException):
+ def test_ignore_exceptions_with_expression_match(self, exc_info, mock_capture):
exc_info.return_value = self.exc_info
- get_option.return_value = ['builtins.*']
- if not six.PY3:
- get_option.return_value = ['exceptions.*']
+
+ if six.PY3:
+ get_client().ignore_exceptions = set(['builtins.*'])
+ else:
+ get_client().ignore_exceptions = set(['exceptions.*'])
sentry_exception_handler(request=self.request)
- assert not captureException.called
+ assert not mock_capture.called
- @mock.patch.object(TempStoreClient, 'captureException')
+ @mock.patch.object(TempStoreClient, 'capture')
@mock.patch('sys.exc_info')
- @mock.patch('raven.contrib.django.models.get_option')
- def test_ignore_exceptions_with_module_match(self, get_option, exc_info, captureException):
+ def test_ignore_exceptions_with_module_match(self, exc_info, mock_capture):
exc_info.return_value = self.exc_info
- get_option.return_value = ['builtins.ValueError']
- if not six.PY3:
- get_option.return_value = ['exceptions.ValueError']
+
+ if six.PY3:
+ get_client().ignore_exceptions = set(['builtins.ValueError'])
+ else:
+ get_client().ignore_exceptions = set(['exceptions.ValueError'])
sentry_exception_handler(request=self.request)
- assert not captureException.called
+ assert not mock_capture.called