(** Error pages. These are deliberately self-contained rather than going through {!Layout}: an error may be raised before a repository context exists, so the page can depend on nothing but the status and message. *) let hint_of_status status = match Dream.status_to_int status with | 400 -> "The request could not be understood. Check the URL for typos or invalid \ characters." | 404 -> "The page or resource you are looking for does not exist. It may have \ been moved or deleted." | 500 -> "Something went wrong on the server. This is not your fault — try again \ later." | code when code >= 400 && code < 500 -> "The request could not be completed. Check the URL and try again." | code when code >= 500 -> "The server encountered an unexpected condition. Try again later." | _ -> "" let render ?(title = "Request failed") ?(status = `Internal_Server_Error) message = let status_code = Dream.status_to_int status |> string_of_int in Ui.respond ~status @@ Ui.document ~head: (Ui.document_head ~title [ Ui.meta_viewport; Ui.stylesheet "/static/styles.css" ]) ~body: (Ui.document_body [ Ui.page_banner ~id:"error-header" [ Ui.inline_text ~class_:"error-code" status_code; Ui.heading [ Ui.text title ]; ]; Ui.page_content ~id:"main" [ Ui.paragraph_text ~class_:"error-hint" (hint_of_status status); Ui.paragraph_text ~class_:"error-detail" message; Ui.paragraph ~class_:"error-nav" [ Ui.text_link ~href:"/" "Return to the repository list" ]; ]; ]) ()