feat descriptive error pages for 4xx and 5xx responses

Error pages now show the numeric status code prominently, a human-friendly hint specific to the error class (400, 404, 5xx), the technical detail message, and a link back to the root page.

Commit
7eb058a2dcefd3088505dd29579a7ec59322aae8
Author
Marius Peter <dev@marius-peter.com>
Author date
Committer
Marius Peter <dev@marius-peter.com>
Committer date
Changed files
lib/static/styles.css
index 7cc8e40a..4838e334 100644..100644
@@ -993,3 +993,39 @@
993 993 font-size: 0.85em;
994 994 }
995 995 }
996 Added:
997 Added:
998 Added: /* Error pages */
999 Added: #error-header {
1000 Added: text-align: center;
1001 Added: padding: 2em 1em 1em;
1002 Added: }
1003 Added:
1004 Added: #error-header .error-code {
1005 Added: display: block;
1006 Added: font-size: 4em;
1007 Added: font-weight: bold;
1008 Added: opacity: 0.3;
1009 Added: line-height: 1;
1010 Added: }
1011 Added:
1012 Added: #error-header h1 {
1013 Added: margin: 0.25em 0 0;
1014 Added: font-size: 1.5em;
1015 Added: }
1016 Added:
1017 Added: .error-hint {
1018 Added: font-size: 1.1em;
1019 Added: margin-bottom: 1em;
1020 Added: }
1021 Added:
1022 Added: .error-detail {
1023 Added: font-family: monospace;
1024 Added: font-size: 0.9em;
1025 Added: opacity: 0.8;
1026 Added: word-break: break-word;
1027 Added: }
1028 Added:
1029 Added: .error-nav {
1030 Added: margin-top: 2em;
1031 Added: }
lib/views/layout.ml
index ca57accf..5775c302 100644..100644
@@ -136,6 +136,24 @@
136 136 let error_page ?(title = "Request failed") ?(status = `Internal_Server_Error)
137 137 message =
138 138 let page_title = title in
139 Added: let status_code = Dream.status_to_int status |> string_of_int in
140 Added: let hint =
141 Added: match Dream.status_to_int status with
142 Added: | 400 ->
143 Added: "The request could not be understood. Check the URL for typos or \
144 Added: invalid characters."
145 Added: | 404 ->
146 Added: "The page or resource you are looking for does not exist. It may have \
147 Added: been moved or deleted."
148 Added: | 500 ->
149 Added: "Something went wrong on the server. This is not your fault — try \
150 Added: again later."
151 Added: | code when code >= 400 && code < 500 ->
152 Added: "The request could not be completed. Check the URL and try again."
153 Added: | code when code >= 500 ->
154 Added: "The server encountered an unexpected condition. Try again later."
155 Added: | _ -> ""
156 Added: in
139 157 let open HTML in
140 158 respond ~status
141 159 @@ html []
@@ -151,17 +169,22 @@
151 169 ];
152 170 body []
153 171 [
154 Removed: h1 [] [ txt "%s" page_title ];
155 Removed: div
156 Removed: [ id "main" ]
172 Added: header
173 Added: [ id "error-header" ]
157 174 [
158 Removed: p [] [ b [] [ txt "%s" message ] ];
159 Removed: p []
160 Removed: [
161 Removed: txt
162 Removed: "Your best course of action is to press the 'back' \
163 Removed: button in your browser.";
164 Removed: ];
175 Added: span [ class_ "error-code" ] [ txt "%s" status_code ];
176 Added: h1 [] [ txt "%s" page_title ];
165 177 ];
178 Added: div
179 Added: [ id "main" ]
180 Added: ([
181 Added: p [ class_ "error-hint" ] [ txt "%s" hint ];
182 Added: p [ class_ "error-detail" ] [ txt "%s" message ];
183 Added: ]
184 Added: @ [
185 Added: p
186 Added: [ class_ "error-nav" ]
187 Added: [ a [ href "/" ] [ txt "Return to the repository list" ] ];
188 Added: ]);
166 189 ];
167 190 ]