diff options
author | David Cramer <dcramer@gmail.com> | 2016-08-03 13:43:05 -0700 |
---|---|---|
committer | David Cramer <dcramer@gmail.com> | 2016-08-03 14:20:17 -0700 |
commit | 93dd4ab82fd611812392d760f577b2fe71f80f19 (patch) | |
tree | 38f85393447242a8894fbd9e6a6e86957ce32129 | |
parent | a0c1ed7ae8c2e08d40c1e93fc9c212b14981bad2 (diff) | |
download | raven-93dd4ab82fd611812392d760f577b2fe71f80f19.tar.gz |
Unify option configuration between Flask/Djangounify-options
Fixes GH-819
@getsentry/python
-rw-r--r-- | raven/contrib/django/models.py | 34 | ||||
-rw-r--r-- | raven/contrib/flask.py | 52 | ||||
-rw-r--r-- | raven/utils/conf.py | 61 | ||||
-rw-r--r-- | tests/contrib/flask/tests.py | 21 | ||||
-rw-r--r-- | tests/utils/test_conf.py | 20 |
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' |