diff --git a/src/pretix/base/__init__.py b/src/pretix/base/__init__.py index c89a3fad7c..d9d7652b0c 100644 --- a/src/pretix/base/__init__.py +++ b/src/pretix/base/__init__.py @@ -1,4 +1,5 @@ from django.apps import AppConfig +from django.conf import settings class PretixBaseConfig(AppConfig): @@ -17,6 +18,10 @@ class PretixBaseConfig(AppConfig): except ImportError: pass + if hasattr(settings, 'RAVEN_CONFIG'): + from ..sentry import initialize + initialize() + default_app_config = 'pretix.base.PretixBaseConfig' try: diff --git a/src/pretix/base/templates/500.html b/src/pretix/base/templates/500.html index 51a67b211a..409f3e30d1 100644 --- a/src/pretix/base/templates/500.html +++ b/src/pretix/base/templates/500.html @@ -6,6 +6,15 @@

{% trans "Internal Server Error" %}

{% trans "We had trouble processing your request." %}

{% trans "If this problem persists, please contact us." %}

+ {% if request.sentry.id %} +

+ {% blocktrans trimmed %} + If you contact us, please send us the following code: + {% endblocktrans %} +
+ {{ request.sentry.id }} +

+ {% endif %}

{{ exception }}

Server Error (500)

', content_type='text/html') + return HttpResponseServerError(template.render({ + 'request': request + })) diff --git a/src/pretix/celery_app.py b/src/pretix/celery_app.py index 4a5a598f73..b451c0dd5a 100644 --- a/src/pretix/celery_app.py +++ b/src/pretix/celery_app.py @@ -9,10 +9,3 @@ from django.conf import settings app = Celery('pretix') app.config_from_object('django.conf:settings', namespace='CELERY') app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) - - -if hasattr(settings, 'RAVEN_CONFIG'): - # Celery signal registration - from raven.contrib.celery import register_signal - from raven.contrib.django.models import client - register_signal(client, ignore_expected=True) diff --git a/src/pretix/multidomain/maindomain_urlconf.py b/src/pretix/multidomain/maindomain_urlconf.py index bd7bf25093..45be79040a 100644 --- a/src/pretix/multidomain/maindomain_urlconf.py +++ b/src/pretix/multidomain/maindomain_urlconf.py @@ -49,3 +49,4 @@ plugin_patterns = [ urlpatterns = common_patterns + plugin_patterns + presale_patterns_main handler404 = 'pretix.base.views.errors.page_not_found' +handler500 = 'pretix.base.views.errors.server_error' diff --git a/src/pretix/multidomain/subdomain_urlconf.py b/src/pretix/multidomain/subdomain_urlconf.py index d3cf991740..eefb5b4843 100644 --- a/src/pretix/multidomain/subdomain_urlconf.py +++ b/src/pretix/multidomain/subdomain_urlconf.py @@ -42,3 +42,4 @@ plugin_patterns = [ urlpatterns = common_patterns + plugin_patterns + presale_patterns handler404 = 'pretix.base.views.errors.page_not_found' +handler500 = 'pretix.base.views.errors.server_error' diff --git a/src/pretix/sentry.py b/src/pretix/sentry.py new file mode 100644 index 0000000000..d7a07d117f --- /dev/null +++ b/src/pretix/sentry.py @@ -0,0 +1,41 @@ +from threading import Lock + +from raven.contrib.celery import SentryCeleryHandler +from raven.contrib.django.apps import RavenConfig +from raven.contrib.django.models import ( + SentryDjangoHandler, client, get_client, install_middleware, + register_serializers, +) + +_setup_lock = Lock() + +_initialized = False + + +class CustomSentryDjangoHandler(SentryDjangoHandler): + def install_celery(self): + self.celery_handler = SentryCeleryHandler(client, ignore_expected=True).install() + + +def initialize(): + global _initialized + + with _setup_lock: + if _initialized: + return + + register_serializers() + install_middleware() + + handler = CustomSentryDjangoHandler() + handler.install() + + # instantiate client so hooks get registered + get_client() # NOQA + + _initialized = True + + +class App(RavenConfig): + def ready(self): + initialize() diff --git a/src/pretix/settings.py b/src/pretix/settings.py index 1f7ff42ded..cfa61e46d6 100644 --- a/src/pretix/settings.py +++ b/src/pretix/settings.py @@ -226,18 +226,6 @@ for entry_point in iter_entry_points(group='pretix.plugin', name=None): PLUGINS.append(entry_point.module_name) INSTALLED_APPS.append(entry_point.module_name) -if config.has_option('sentry', 'dsn'): - INSTALLED_APPS += [ - 'raven.contrib.django.raven_compat', - ] - DISABLE_SENTRY_INSTRUMENTATION = True # see celery.py for more, we use this differently - RAVEN_CONFIG = { - 'dsn': config.get('sentry', 'dsn'), - 'transport': 'raven.transport.threaded_requests.ThreadedRequestsHTTPTransport', - 'release': __version__, - 'environment': SITE_URL, - } - REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ @@ -487,6 +475,17 @@ LOGGING = { }, } +if config.has_option('sentry', 'dsn'): + INSTALLED_APPS += [ + 'pretix.sentry.App', + ] + RAVEN_CONFIG = { + 'dsn': config.get('sentry', 'dsn'), + 'transport': 'raven.transport.threaded_requests.ThreadedRequestsHTTPTransport', + 'release': __version__, + 'environment': SITE_URL, + } + CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json'