use std::fmt; use crate::components; use crate::models; use axum::{ http::StatusCode, response::{IntoResponse, Response}, }; pub enum RequestError { EmptyFormElement { name: String }, RefererNotFound, RefererInvalid { message: String }, NotFound { message: String }, } impl fmt::Display for RequestError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Self::EmptyFormElement { name } => write!(f, "Form element {name} cannot be empty"), Self::RefererNotFound => write!(f, "Referer header not found"), Self::RefererInvalid { message } => write!(f, "Referer header invalid: {message}"), Self::NotFound { message } => write!(f, "Not found: {message}"), } } } pub enum Error { Model(models::Error), Request(RequestError), } #[derive(Debug)] pub enum StartError { DatabaseInitError { message: String }, DatabaseMigrationError { message: String }, } impl From for StartError { fn from(value: sqlx::Error) -> Self { Self::DatabaseInitError { message: value.to_string(), } } } impl From for StartError { fn from(value: sqlx::migrate::MigrateError) -> Self { Self::DatabaseMigrationError { message: value.to_string(), } } } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Self::Model(model_error) => write!(f, "Model error: {model_error}"), Self::Request(request_error) => write!(f, "Request error: {request_error}"), } } } impl From for Error { fn from(value: models::Error) -> Self { Self::Model(value) } } impl IntoResponse for Error { fn into_response(self) -> Response { match self { Self::Model(ref model_error) => match model_error { models::Error::Database(_) => ( StatusCode::INTERNAL_SERVER_ERROR, components::ErrorPage::build(&format!("{}", self)), ), models::Error::Query(error) => match error { models::QueryError::NotFound { description } => ( StatusCode::NOT_FOUND, components::ErrorPage::build(&description), ), _ => ( StatusCode::BAD_REQUEST, components::ErrorPage::build(&format!("{}", error)), ), }, }, Self::Request(request_error) => match request_error { RequestError::RefererNotFound => ( StatusCode::BAD_REQUEST, components::ErrorPage::build("no referer header found"), ), RequestError::RefererInvalid { message } => ( StatusCode::BAD_REQUEST, components::ErrorPage::build(&format!( "referer could not be converted: {}", message )), ), RequestError::EmptyFormElement { name } => ( StatusCode::UNPROCESSABLE_ENTITY, components::ErrorPage::build(&format!("empty form element: {}", name)), ), RequestError::NotFound { message } => ( StatusCode::NOT_FOUND, components::ErrorPage::build(&format!("not found: {}", message)), ), }, } .into_response() } }