diff --git a/bugsink/urls.py b/bugsink/urls.py index 72b3706..c2ac375 100644 --- a/bugsink/urls.py +++ b/bugsink/urls.py @@ -63,3 +63,6 @@ if settings.DEBUG: path('trigger-error/', trigger_error), path("__debug__/", include("debug_toolbar.urls")), ] + + +handler500 = "bugsink.views.server_error" diff --git a/bugsink/views.py b/bugsink/views.py index 1fcd515..6768113 100644 --- a/bugsink/views.py +++ b/bugsink/views.py @@ -1,3 +1,9 @@ +import sys + +from django.http import HttpResponseServerError +from django.template import TemplateDoesNotExist, loader +from django.views.decorators.csrf import requires_csrf_token +from django.views.defaults import ERROR_500_TEMPLATE_NAME, ERROR_PAGE_TEMPLATE from django.shortcuts import redirect from django.conf import settings @@ -108,3 +114,22 @@ def settings_view(request): "misc_settings": misc_settings, "version": __version__, }) + + +@requires_csrf_token +def server_error(request, template_name=ERROR_500_TEMPLATE_NAME): + # verbatim copy of Django's default server_error view, but with "exception" in the context + # doing this for any-old-Django-site is probably a bad idea, but here the security/convenience tradeoff is fine, + # especially because we only show str(exception) in the template. + try: + template = loader.get_template(template_name) + except TemplateDoesNotExist: + if template_name != ERROR_500_TEMPLATE_NAME: + # Reraise if it's a missing custom template. + raise + return HttpResponseServerError( + ERROR_PAGE_TEMPLATE % {"title": "Server Error (500)", "details": ""}, + ) + + _, exception, _ = sys.exc_info() + return HttpResponseServerError(template.render({"exception": exception}, request)) diff --git a/templates/500.html b/templates/500.html index dda273e..4190b48 100644 --- a/templates/500.html +++ b/templates/500.html @@ -6,7 +6,16 @@