summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Cramer <dcramer@gmail.com>2016-08-03 13:43:05 -0700
committerDavid Cramer <dcramer@gmail.com>2016-08-03 14:20:17 -0700
commit93dd4ab82fd611812392d760f577b2fe71f80f19 (patch)
tree38f85393447242a8894fbd9e6a6e86957ce32129
parenta0c1ed7ae8c2e08d40c1e93fc9c212b14981bad2 (diff)
downloadraven-93dd4ab82fd611812392d760f577b2fe71f80f19.tar.gz
Unify option configuration between Flask/Djangounify-options
Fixes GH-819 @getsentry/python
-rw-r--r--raven/contrib/django/models.py34
-rw-r--r--raven/contrib/flask.py52
-rw-r--r--raven/utils/conf.py61
-rw-r--r--tests/contrib/flask/tests.py21
-rw-r--r--tests/utils/test_conf.py20
5 files changed, 107 insertions, 81 deletions
diff --git a/raven/contrib/django/models.py b/raven/contrib/django/models.py
index bad6fc3..2e48d5f 100644
--- a/raven/contrib/django/models.py
+++ b/raven/contrib/django/models.py
@@ -11,18 +11,16 @@ Acts as an implicit hook for Django installs.
from __future__ import absolute_import, unicode_literals
-import copy
import logging
import sys
import warnings
from django.conf import settings
-from hashlib import md5
from raven._compat import PY2, binary_type, text_type, string_types
-from raven.utils.imports import import_string
from raven.contrib.django.management import patch_cli_runner
-
+from raven.utils.conf import convert_options
+from raven.utils.imports import import_string
logger = logging.getLogger('sentry.errors.client')
@@ -121,28 +119,12 @@ def get_client(client=None, reset=False):
client = getattr(settings, 'SENTRY_CLIENT', 'raven.contrib.django.DjangoClient')
if _client[0] != client or reset:
- ga = lambda x, d=None: getattr(settings, 'SENTRY_%s' % x, d)
- options = copy.deepcopy(getattr(settings, 'RAVEN_CONFIG', {}))
- options.setdefault('include_paths', ga('INCLUDE_PATHS', []))
- if not options['include_paths']:
- options['include_paths'] = get_installed_apps()
- options.setdefault('exclude_paths', ga('EXCLUDE_PATHS'))
- options.setdefault('timeout', ga('TIMEOUT'))
- options.setdefault('name', ga('NAME'))
- options.setdefault('auto_log_stacks', ga('AUTO_LOG_STACKS'))
- options.setdefault('string_max_length', ga('MAX_LENGTH_STRING'))
- options.setdefault('list_max_length', ga('MAX_LENGTH_LIST'))
- options.setdefault('site', ga('SITE'))
- options.setdefault('processors', ga('PROCESSORS'))
- 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):
- transport = import_string(transport)
- options['transport'] = transport
+ options = convert_options(
+ settings,
+ defaults={
+ 'include_paths': get_installed_apps(),
+ },
+ )
try:
Client = import_string(client)
diff --git a/raven/contrib/flask.py b/raven/contrib/flask.py
index c23b92b..df7423a 100644
--- a/raven/contrib/flask.py
+++ b/raven/contrib/flask.py
@@ -15,49 +15,41 @@ except ImportError:
else:
has_flask_login = True
-import sys
-import os
import logging
from flask import request, current_app, g
from flask.signals import got_request_exception, request_finished
from werkzeug.exceptions import ClientDisconnected
-from raven._compat import string_types
from raven.conf import setup_logging
from raven.base import Client
from raven.middleware import Sentry as SentryMiddleware
from raven.handlers.logging import SentryHandler
from raven.utils.compat import _urlparse
from raven.utils.encoding import to_unicode
-from raven.utils.imports import import_string
from raven.utils.wsgi import get_headers, get_environ
+from raven.utils.conf import convert_options
def make_client(client_cls, app, dsn=None):
- # TODO(dcramer): django and Flask share very similar concepts here, and
- # should be refactored
- transport = app.config.get('SENTRY_TRANSPORT')
- if isinstance(transport, string_types):
- transport = import_string(transport)
-
return client_cls(
- dsn=dsn or app.config.get('SENTRY_DSN') or os.environ.get('SENTRY_DSN'),
- transport=transport,
- include_paths=set(app.config.get(
- 'SENTRY_INCLUDE_PATHS', [])) | set([app.import_name]),
- exclude_paths=app.config.get('SENTRY_EXCLUDE_PATHS'),
- name=app.config.get('SENTRY_NAME'),
- site=app.config.get('SENTRY_SITE_NAME'),
- processors=app.config.get('SENTRY_PROCESSORS'),
- string_max_length=app.config.get('SENTRY_MAX_LENGTH_STRING'),
- list_max_length=app.config.get('SENTRY_MAX_LENGTH_LIST'),
- auto_log_stacks=app.config.get('SENTRY_AUTO_LOG_STACKS'),
- tags=app.config.get('SENTRY_TAGS'),
- release=app.config.get('SENTRY_RELEASE'),
- extra={
- 'app': app,
- },
+ **convert_options(
+ app.config,
+ defaults={
+ 'include_paths': (
+ set(app.config.get('SENTRY_INCLUDE_PATHS', []))
+ | 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', [])
+ ],
+ 'extra': {
+ 'app': app,
+ },
+ },
+ )
)
@@ -136,14 +128,6 @@ class Sentry(object):
if not self.client:
return
- ignored_exc_type_list = current_app.config.get(
- 'RAVEN_IGNORE_EXCEPTIONS', [])
- exc = sys.exc_info()[1]
-
- if any((isinstance(exc, ignored_exc_type)
- for ignored_exc_type in ignored_exc_type_list)):
- return
-
self.captureException(exc_info=kwargs.get('exc_info'))
def get_user_info(self, request):
diff --git a/raven/utils/conf.py b/raven/utils/conf.py
new file mode 100644
index 0000000..4cf8c0d
--- /dev/null
+++ b/raven/utils/conf.py
@@ -0,0 +1,61 @@
+from __future__ import absolute_import
+
+import copy
+import os
+
+from raven._compat import string_types
+from raven.utils.imports import import_string
+
+
+def convert_options(settings, defaults=None):
+ """
+ Convert a settings object (or dictionary) to parameters which may be passed
+ to a new ``Client()`` instance.
+ """
+ if defaults is None:
+ defaults = {}
+
+ if isinstance(settings, dict):
+ def getopt(key, default=None):
+ return settings.get(
+ 'SENTRY_%s' % key.upper(),
+ defaults.get(key, default)
+ )
+
+ options = copy.copy(
+ settings.get('SENTRY_CONFIG')
+ or settings.get('RAVEN_CONFIG')
+ or {}
+ )
+ else:
+ def getopt(key, default=None):
+ return getattr(settings, 'SENTRY_%s' % key.upper(), defaults.get(key, default))
+
+ options = copy.copy(
+ getattr(settings, 'SENTRY_CONFIG', None)
+ or getattr(settings, 'RAVEN_CONFIG', None)
+ or {}
+ )
+
+ options.setdefault('include_paths', getopt('include_paths', []))
+ options.setdefault('exclude_paths', getopt('exclude_paths', []))
+ options.setdefault('timeout', getopt('timeout'))
+ options.setdefault('name', getopt('name'))
+ options.setdefault('auto_log_stacks', getopt('auto_log_stacks'))
+ options.setdefault('string_max_length', getopt('string_max_length'))
+ options.setdefault('list_max_length', getopt('list_max_length'))
+ options.setdefault('site', getopt('site'))
+ options.setdefault('processors', getopt('processors'))
+ options.setdefault('dsn', getopt('dsn', os.environ.get('SENTRY_DSN')))
+ options.setdefault('context', getopt('context'))
+ options.setdefault('tags', getopt('tags'))
+ options.setdefault('release', getopt('release'))
+ options.setdefault('environment', getopt('environment'))
+ options.setdefault('ignore_exceptions', getopt('ignore_exceptions'))
+
+ transport = getopt('transport') or options.get('transport')
+ if isinstance(transport, string_types):
+ transport = import_string(transport)
+ options['transport'] = transport
+
+ return options
diff --git a/tests/contrib/flask/tests.py b/tests/contrib/flask/tests.py
index 0530216..36bf573 100644
--- a/tests/contrib/flask/tests.py
+++ b/tests/contrib/flask/tests.py
@@ -228,27 +228,6 @@ class FlaskTest(BaseTest):
_, _, app_ndebug = self.make_client_and_raven(debug=False)
self.assertTrue(app_ndebug.extensions['sentry'].wrap_wsgi)
- def test_error_handler_with_ignored_exception(self):
- client, raven, _ = self.make_client_and_raven(ignore_exceptions=[NameError, ValueError])
-
- response = client.get('/an-error/')
- self.assertEquals(response.status_code, 500)
- self.assertEquals(len(raven.events), 0)
-
- def test_error_handler_with_exception_not_ignored(self):
- client, raven, _ = self.make_client_and_raven(ignore_exceptions=[NameError, KeyError])
-
- response = client.get('/an-error/')
- self.assertEquals(response.status_code, 500)
- self.assertEquals(len(raven.events), 1)
-
- def test_error_handler_with_empty_ignore_exceptions_list(self):
- client, raven, _ = self.make_client_and_raven(ignore_exceptions=[])
-
- response = client.get('/an-error/')
- self.assertEquals(response.status_code, 500)
- self.assertEquals(len(raven.events), 1)
-
def test_captureException_sets_last_event_id(self):
with self.app.test_request_context('/'):
try:
diff --git a/tests/utils/test_conf.py b/tests/utils/test_conf.py
new file mode 100644
index 0000000..0a9221e
--- /dev/null
+++ b/tests/utils/test_conf.py
@@ -0,0 +1,20 @@
+from __future__ import absolute_import
+
+from raven.utils.conf import convert_options
+
+
+def test_convert_options_parses_dict():
+ options = convert_options({
+ 'SENTRY_FOO': 'foo',
+ 'FOO': 'bar',
+ 'SENTRY_RELEASE': 'a',
+ 'SENTRY_IGNORE_EXCEPTIONS': [
+ 'b',
+ ]
+ }, defaults={'environment': 'production'})
+
+ assert options['release'] == 'a'
+ assert options['ignore_exceptions'] == [
+ 'b',
+ ]
+ assert options['environment'] == 'production'