Skip to content

Commit

Permalink
Add generic error pages for Django
Browse files Browse the repository at this point in the history
Each of Django's handlers wraps the generic error() view since all we
really want in this application is a page saying something has gone
wrong.
  • Loading branch information
ghickman committed Jul 13, 2023
1 parent 18d76e5 commit 62685da
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 1 deletion.
1 change: 1 addition & 0 deletions assets/src/scripts/error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "../styles/error.css";
9 changes: 9 additions & 0 deletions assets/src/styles/error.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
body {
grid-template-rows: 1fr max-content 1fr;
grid-template-columns: 1fr;
}

body > div {
grid-template-rows: 1fr;
grid-template-columns: 1fr min-content 1fr;
}
31 changes: 31 additions & 0 deletions sacro/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from django.template.response import TemplateResponse


def error(request, *, status=500, message=""):
"""Generic error view"""
return TemplateResponse(
request,
"error.html",
status=status,
context={"message": message},
)


def bad_request(request, exception=None):
return error(request, status=400)


def csrf_failure(request, reason=""):
return error(request, status=400)


def page_not_found(request, exception=None):
return error(request, status=404)


def permission_denied(request, exception=None):
return error(request, status=403)


def server_error(request):
return error(request)
1 change: 1 addition & 0 deletions sacro/templates/components.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ components:
icon_breadcrumb_arrow: "icons/breadcrumb-arrow.svg"
icon_check: "icons/check.svg"
icon_document_outline: "icons/document-outline.svg"
icon_exclamation_triangle: "icons/exclamation-triangle.svg"
icon_file: "icons/file.svg"
icon_file_unknown: "icons/file-unknown.svg"
icon_file_x: "icons/file-x.svg"
Expand Down
33 changes: 33 additions & 0 deletions sacro/templates/error.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{% load django_vite %}

<!DOCTYPE html>
<html lang="en" class="min-h-screen">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>SACRO Outputs Viewer</title>

{% vite_hmr_client %}
{% vite_asset "assets/src/scripts/base.js" %}
{% vite_asset "assets/src/scripts/error.js" %}
</head>

<body class="grid h-screen">
<div class="row-start-2 grid">
<div class="col-start-2 flex flex-col gap-3 text-center w-screen">
<div class="flex justify-center">
{% icon_exclamation_triangle class="h-32 w-32 stroke-slate-700" %}
</div>

<p class="break-normal">
The application encourtered a problem. Please restart the application and try
again. If this problem continues please contact support.
</p>

<p class="break-words">{{ message }}</p>
</div>
</div>

</body>
</html>
3 changes: 3 additions & 0 deletions sacro/templates/icons/exclamation-triangle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 8 additions & 1 deletion sacro/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
from django.conf import settings
from django.urls import include, path

from sacro import views
from sacro import errors, views


urlpatterns = [
path("", views.index, name="index"),
path("contents/", views.contents, name="contents"),
path("error/", errors.error, name="error"),
path("review/", views.review_create, name="review-create"),
path("review/<str:pk>/", views.review_detail, name="review-detail"),
path(
Expand All @@ -23,3 +24,9 @@
"django_browser_reload"
): # pragma: no cover
urlpatterns.append(path("__reload__/", include("django_browser_reload.urls")))


handler400 = errors.bad_request
handler403 = errors.permission_denied
handler404 = errors.page_not_found
handler500 = errors.server_error
57 changes: 57 additions & 0 deletions tests/test_errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from sacro.errors import (
bad_request,
csrf_failure,
error,
page_not_found,
permission_denied,
server_error,
)


def test_bad_request(rf):
request = rf.get("/")

response = bad_request(request)

assert response.status_code == 400


def test_csrf_failure(rf):
request = rf.get("/")

response = csrf_failure(request)

assert response.status_code == 400


def test_error_with_message(rf):
request = rf.get("/")

response = error(request, message="testing")

assert response.status_code == 500
assert "testing" in response.rendered_content


def test_permission_denied(rf):
request = rf.get("/")

response = permission_denied(request)

assert response.status_code == 403


def test_page_not_found(rf):
request = rf.get("/")

response = page_not_found(request)

assert response.status_code == 404


def test_server_error(rf):
request = rf.get("/")

response = server_error(request)

assert response.status_code == 500
1 change: 1 addition & 0 deletions vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default defineConfig({
rollupOptions: {
input: [
"./assets/src/scripts/base.js",
"./assets/src/scripts/error.js",
"./assets/src/scripts/index.js",
"./assets/src/scripts/review.js",
],
Expand Down

0 comments on commit 62685da

Please sign in to comment.