Friendly 400 page that shows the error, even when DEBUG=False

when people run into ALLOWED_HOSTS troubles, they should get info on-screen ASAP
This commit is contained in:
Klaas van Schelven
2024-11-28 12:43:14 +01:00
parent e7ddfa0855
commit 719fcae322
5 changed files with 43 additions and 10 deletions

View File

@@ -83,5 +83,6 @@ def useful_settings_processor(request):
def logged_in_user_processor(request):
return {
'logged_in_user': request.user,
# getattr, because if there's a failure "very early" in the request handling, we don't have an AnonymousUser
'logged_in_user': getattr(request, "user", None),
}

View File

@@ -65,4 +65,5 @@ if settings.DEBUG:
]
handler400 = "bugsink.views.bad_request"
handler500 = "bugsink.views.server_error"

View File

@@ -1,9 +1,9 @@
import sys
from django.http import HttpResponseServerError
from django.http import HttpResponseServerError, HttpResponseBadRequest
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.views.defaults import ERROR_500_TEMPLATE_NAME, ERROR_PAGE_TEMPLATE, ERROR_400_TEMPLATE_NAME
from django.shortcuts import redirect
from django.conf import settings
@@ -116,6 +116,25 @@ def settings_view(request):
})
@requires_csrf_token
def bad_request(request, exception, template_name=ERROR_400_TEMPLATE_NAME):
# verbatim copy of Django's default bad_request 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_400_TEMPLATE_NAME:
# Reraise if it's a missing custom template.
raise
return HttpResponseBadRequest(
ERROR_PAGE_TEMPLATE % {"title": "Bad Request (400)", "details": ""},
)
_, exception, _ = sys.exc_info()
return HttpResponseBadRequest(template.render({"exception": exception}, request))
@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

View File

@@ -1,9 +1,9 @@
def user_projects_processor(request):
if not request.user.is_authenticated:
return {
'user_projects': [],
}
if not hasattr(request, "user"):
# check, because if there's a failure "very early" in the request handling, we don't have an AnonymousUser
return {"user_projects": []}
return {
'user_projects': request.user.project_set.all(),
}
if not request.user.is_authenticated:
return {'user_projects': []}
return {'user_projects': request.user.project_set.all()}

12
templates/400.html Normal file
View File

@@ -0,0 +1,12 @@
{% extends "bare_base.html" %}
{% block title %}400 Server Error{% endblock %}
{% block content %}
<div class="m-4">
<h1 class="text-4xl mt-4 font-bold">400 Server Error</h1>
<div class="pt-2">
{{ exception }}
</div>
{% endblock %}