{# The page a failed navigation lands on, and only a navigation. An htmx swap is answered with a toast on the page it was already on — see `fjkit.errors` — because replacing one region of a working page with a whole error document is worse than the error. An app replaces this by writing its own `errors/page.html`. The app's template directory is searched before the kit's, so a file at this path wins, the way `fjkit eject` works; there is no separate "custom error page" setting to find. An app doing that usually wants `{% extends "base.html" %}` so the page keeps its nav. This one extends the shell directly, because the kit cannot know what an app called its base. The whole context: status_code 422 or 500 errors `FieldErrors` on a 422, `none` on a 500 No `detail` and no traceback, deliberately. A 500 means the app is in a state nobody predicted, and the honest thing to show a visitor is that something broke. The specifics go to the log, where someone who can act on them reads them. #} {% extends "ui/shell.html" %} {% from "ui/button.html" import button %} {% from "ui/data.html" import bullet_list, card, list_item %} {% from "ui/layout.html" import centered, stack %} {% set _TITLES = { 400: "That request could not be read", 404: "There is nothing at this address", 422: "That form could not be saved", } %} {% set heading = _TITLES.get(status_code, "Something went wrong") %} {% block title %}{{ heading }}{% endblock %} {% block content %} {# `centered` rather than a bare stack. This is the page that shape was added for: an apology and a way out, on a page with no navigation, has no business running to the shell's full 1152px. It is also the only standalone page the kit itself ships, so it is where the macro is used rather than only documented. #} {% call centered("lg", gap=6) %} {% call card(heading) %} {% call stack(4) %} {# The errors are listed rather than dropped: on a 422 they are the point of the page, because the person filled something in and needs to know which part to change. On a 500 `errors` is `none` and the paragraph below is all there is to say. #} {% if errors %} {# `bullet_list`, not a hand-written `
Nothing was saved. Go back, correct the highlighted fields and try again.
{% else %}The action was not completed and nothing was saved. If it keeps happening, the details are in the server log.
{% endif %}