diff --git a/src/controller/mod.rs b/src/controller/mod.rs index 2df69e0..c32bcbb 100644 --- a/src/controller/mod.rs +++ b/src/controller/mod.rs @@ -214,7 +214,7 @@ use axum::{ }, headers::{Cookie, HeaderName}, http::{HeaderMap, HeaderValue, Request, StatusCode}, - response::{Html, IntoResponse, Redirect, Response}, + response::{IntoResponse, Redirect, Response}, routing::{get_service, MethodRouter}, TypedHeader, }; @@ -230,6 +230,7 @@ use std::iter::Rev; use time::{OffsetDateTime, Time}; use tokio::{fs, signal}; use tower_http::services::ServeDir; +use tracing::error; use utils::CURRENT_SHA256; use validator::Validate; @@ -253,6 +254,48 @@ fn into_response(t: &T, ext: &str) -> Response { } } +#[derive(Template)] +#[template(path = "error.html")] +struct PageError<'a> { + page_data: PageData<'a>, + status: String, + error: String, +} + +impl IntoResponse for AppError { + fn into_response(self) -> Response { + let status = match self { + AppError::CaptchaError + | AppError::NameExists + | AppError::InnCreateLimit + | AppError::UsernameInvalid + | AppError::NotFound + | AppError::WrongPassword + | AppError::ImageError(_) + | AppError::Locked + | AppError::Hidden + | AppError::ReadOnly + | AppError::ValidationError(_) + | AppError::AxumFormRejection(_) => StatusCode::BAD_REQUEST, + AppError::WriteInterval => StatusCode::TOO_MANY_REQUESTS, + AppError::NonLogin => return Redirect::to("/signin").into_response(), + AppError::Unauthorized => StatusCode::UNAUTHORIZED, + AppError::Banned => StatusCode::FORBIDDEN, + _ => StatusCode::INTERNAL_SERVER_ERROR, + }; + + error!("{}, {}", status, self); + let page_data = PageData::new("Error", "Error found", None, false); + let page_error = PageError { + page_data, + status: status.to_string(), + error: self.to_string(), + }; + + into_response(&page_error, "html") + } +} + pub(super) struct ValidatedForm(pub(super) T); #[async_trait] @@ -417,14 +460,7 @@ pub(super) async fn serve_dir(path: &str) -> MethodRouter { // TODO: CSS Better style pub(super) async fn handler_404() -> impl IntoResponse { - let html = format!( - r#"Error: -

{}

-

Home

"#, - StatusCode::NOT_FOUND - ); - let body = Html(html); - (StatusCode::NOT_FOUND, body) + AppError::NotFound.into_response() } pub(crate) async fn style() -> (HeaderMap, String) { diff --git a/src/error.rs b/src/error.rs index 55b7e6a..d78ffd0 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,7 +1,4 @@ -use axum::{ - http::{uri::InvalidUri, StatusCode}, - response::{Html, IntoResponse, Redirect, Response}, -}; +use axum::http::uri::InvalidUri; use thiserror::Error; use tracing::error; @@ -61,40 +58,3 @@ pub(super) enum AppError { #[error(transparent)] AxumFormRejection(#[from] axum::extract::rejection::FormRejection), } - -// TODO: CSS Better style -impl IntoResponse for AppError { - fn into_response(self) -> Response { - let status = match self { - AppError::CaptchaError - | AppError::NameExists - | AppError::InnCreateLimit - | AppError::UsernameInvalid - | AppError::NotFound - | AppError::WrongPassword - | AppError::ImageError(_) - | AppError::Locked - | AppError::Hidden - | AppError::ReadOnly - | AppError::ValidationError(_) - | AppError::AxumFormRejection(_) => StatusCode::BAD_REQUEST, - AppError::WriteInterval => StatusCode::TOO_MANY_REQUESTS, - AppError::NonLogin => return Redirect::to("/signin").into_response(), - AppError::Unauthorized => StatusCode::UNAUTHORIZED, - AppError::Banned => StatusCode::FORBIDDEN, - _ => StatusCode::INTERNAL_SERVER_ERROR, - }; - - error!("{}, {}", status, self); - - let html = format!( - r#"Error: {} -

{}

-

Home

"#, - status, self - ); - let body = Html(html); - - (status, body).into_response() - } -} diff --git a/templates/error.html b/templates/error.html new file mode 100644 index 0000000..385d8ef --- /dev/null +++ b/templates/error.html @@ -0,0 +1,15 @@ +{% extends "layout.html" %} + +{% block menu_right %} +{% endblock %} + +{% block content %} +
+
+

{{status}}

+

Error: {{error}}

+
+
+ +
+{% endblock %} \ No newline at end of file