mcaptcha/pages/
errors.rs

1// Copyright (C) 2022  Aravinth Manivannan <realaravinth@batsense.net>
2// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
3//
4// SPDX-License-Identifier: AGPL-3.0-or-later
5
6use 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}