1use actix_web::{web, HttpResponse, Responder};
7use lazy_static::lazy_static;
8use sailfish::TemplateOnce;
9
10use crate::errors::PageError;
11
12#[derive(Clone, TemplateOnce)]
13#[template(path = "errors/index.html")]
14struct ErrorPage<'a> {
15 title: &'a str,
16 message: &'a str,
17}
18
19const PAGE: &str = "Error";
20
21impl<'a> ErrorPage<'a> {
22 fn new(title: &'a str, message: &'a str) -> Self {
23 ErrorPage { title, message }
24 }
25}
26
27lazy_static! {
28 static ref INTERNAL_SERVER_ERROR_BODY: String = ErrorPage::new(
29 "Internal Server Error",
30 &format!("{}", PageError::InternalServerError),
31 )
32 .render_once()
33 .unwrap();
34 static ref UNKNOWN_ERROR_BODY: String = ErrorPage::new(
35 "Something went wrong",
36 &format!("{}", PageError::InternalServerError),
37 )
38 .render_once()
39 .unwrap();
40}
41
42const ERROR_ROUTE: &str = "/error/{id}";
43
44#[my_codegen::get(path = "ERROR_ROUTE")]
45async fn error(path: web::Path<usize>) -> impl Responder {
46 let resp = match path.into_inner() {
47 500 => HttpResponse::InternalServerError()
48 .content_type("text/html; charset=utf-8")
49 .body(&**INTERNAL_SERVER_ERROR_BODY),
50
51 _ => HttpResponse::InternalServerError()
52 .content_type("text/html; charset=utf-8")
53 .body(&**UNKNOWN_ERROR_BODY),
54 };
55
56 resp
57}
58
59pub fn services(cfg: &mut web::ServiceConfig) {
60 cfg.service(error);
61}
62
63pub mod routes {
64 pub struct Errors {
65 pub internal_server_error: &'static str,
66 pub unknown_error: &'static str,
67 }
68
69 impl Errors {
70 pub const fn new() -> Self {
71 Errors {
72 internal_server_error: "/error/500",
73 unknown_error: "/error/007",
74 }
75 }
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use actix_web::{http::StatusCode, test, App};
82
83 use super::*;
84 use crate::PAGES;
85
86 #[actix_rt::test]
87 async fn error_pages_work() {
88 let app = test::init_service(App::new().configure(services)).await;
89
90 let resp = test::call_service(
91 &app,
92 test::TestRequest::get()
93 .uri(PAGES.errors.internal_server_error)
94 .to_request(),
95 )
96 .await;
97 assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
98
99 let resp = test::call_service(
100 &app,
101 test::TestRequest::get()
102 .uri(PAGES.errors.unknown_error)
103 .to_request(),
104 )
105 .await;
106 assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
107 }
108}