Files
packager/rust/src/error.rs

203 lines
6.6 KiB
Rust
Raw Normal View History

2023-08-29 21:34:00 +02:00
use std::fmt;
use crate::models;
2023-08-29 21:34:00 +02:00
use crate::view;
2023-08-29 21:34:00 +02:00
use axum::{
http::StatusCode,
response::{IntoResponse, Response},
};
2023-08-29 21:34:00 +02:00
#[derive(Debug)]
2023-08-29 21:34:00 +02:00
pub enum RequestError {
EmptyFormElement { name: String },
RefererNotFound,
RefererInvalid { message: String },
NotFound { message: String },
2023-08-29 21:34:00 +02:00
AuthenticationUserNotFound { username: String },
AuthenticationHeaderMissing,
AuthenticationHeaderInvalid { message: String },
2023-08-29 21:34:00 +02:00
Transport { inner: hyper::Error },
2023-08-29 21:34:00 +02:00
}
2023-08-29 21:34:00 +02:00
impl std::error::Error for RequestError {}
2023-08-29 21:34:00 +02:00
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}"),
2023-08-29 21:34:00 +02:00
Self::AuthenticationUserNotFound { username } => {
write!(f, "User \"{username}\" not found")
}
Self::AuthenticationHeaderMissing => write!(f, "Authentication header not found"),
Self::AuthenticationHeaderInvalid { message } => {
write!(f, "Authentication header invalid: {message}")
}
2023-08-29 21:34:00 +02:00
Self::Transport { inner } => {
write!(f, "HTTP error: {inner}")
}
2023-08-29 21:34:00 +02:00
}
}
}
2023-08-29 21:34:00 +02:00
#[derive(Debug)]
2023-08-29 21:34:00 +02:00
pub enum Error {
Model(models::Error),
Request(RequestError),
2023-08-29 21:34:00 +02:00
Start(StartError),
Command(CommandError),
2023-08-29 21:34:00 +02:00
}
2023-08-29 21:34:00 +02:00
impl std::error::Error for Error {}
2023-08-29 21:34:00 +02:00
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}"),
2023-08-29 21:34:00 +02:00
Self::Start(start_error) => write!(f, "{start_error}"),
Self::Command(command_error) => write!(f, "{command_error}"),
2023-08-29 21:34:00 +02:00
}
}
}
impl From<models::Error> for Error {
fn from(value: models::Error) -> Self {
Self::Model(value)
}
}
2023-08-29 21:34:00 +02:00
impl From<StartError> for Error {
fn from(value: StartError) -> Self {
Self::Start(value)
}
}
impl From<hyper::Error> for Error {
fn from(value: hyper::Error) -> Self {
Self::Request(RequestError::Transport { inner: value })
}
}
2023-08-29 21:34:00 +02:00
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,
2023-08-29 21:34:00 +02:00
view::ErrorPage::build(&format!("{}", self)),
2023-08-29 21:34:00 +02:00
),
models::Error::Query(error) => match error {
2023-08-29 21:34:00 +02:00
models::QueryError::NotFound { description } => {
(StatusCode::NOT_FOUND, view::ErrorPage::build(&description))
}
2023-08-29 21:34:00 +02:00
_ => (
StatusCode::BAD_REQUEST,
2023-08-29 21:34:00 +02:00
view::ErrorPage::build(&format!("{}", error)),
2023-08-29 21:34:00 +02:00
),
},
},
Self::Request(request_error) => match request_error {
RequestError::RefererNotFound => (
StatusCode::BAD_REQUEST,
2023-08-29 21:34:00 +02:00
view::ErrorPage::build("no referer header found"),
2023-08-29 21:34:00 +02:00
),
RequestError::RefererInvalid { message } => (
StatusCode::BAD_REQUEST,
2023-08-29 21:34:00 +02:00
view::ErrorPage::build(&format!("referer could not be converted: {}", message)),
2023-08-29 21:34:00 +02:00
),
RequestError::EmptyFormElement { name } => (
StatusCode::UNPROCESSABLE_ENTITY,
2023-08-29 21:34:00 +02:00
view::ErrorPage::build(&format!("empty form element: {}", name)),
2023-08-29 21:34:00 +02:00
),
RequestError::NotFound { message } => (
StatusCode::NOT_FOUND,
2023-08-29 21:34:00 +02:00
view::ErrorPage::build(&format!("not found: {}", message)),
2023-08-29 21:34:00 +02:00
),
2023-08-29 21:34:00 +02:00
RequestError::AuthenticationUserNotFound { username: _ } => (
StatusCode::BAD_REQUEST,
view::ErrorPage::build(&request_error.to_string()),
),
RequestError::AuthenticationHeaderMissing => (
StatusCode::UNAUTHORIZED,
view::ErrorPage::build(&request_error.to_string()),
),
RequestError::AuthenticationHeaderInvalid { message: _ } => (
StatusCode::UNAUTHORIZED,
view::ErrorPage::build(&request_error.to_string()),
),
2023-08-29 21:34:00 +02:00
RequestError::Transport { inner } => (
StatusCode::INTERNAL_SERVER_ERROR,
view::ErrorPage::build(&inner.to_string()),
),
2023-08-29 21:34:00 +02:00
},
2023-08-29 21:34:00 +02:00
Self::Start(start_error) => (
StatusCode::INTERNAL_SERVER_ERROR,
view::ErrorPage::build(&start_error.to_string()),
),
Self::Command(command_error) => (
StatusCode::INTERNAL_SERVER_ERROR,
view::ErrorPage::build(&command_error.to_string()),
),
2023-08-29 21:34:00 +02:00
}
.into_response()
}
}
2023-08-29 21:34:00 +02:00
#[derive(Debug)]
pub enum StartError {
DatabaseInitError { message: String },
DatabaseMigrationError { message: String },
}
impl std::error::Error for StartError {}
impl fmt::Display for StartError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::DatabaseInitError { message } => {
write!(f, "database initialization error: {message}")
}
Self::DatabaseMigrationError { message } => {
write!(f, "database migration error: {message}")
}
}
}
}
impl From<sqlx::Error> for StartError {
fn from(value: sqlx::Error) -> Self {
Self::DatabaseInitError {
message: value.to_string(),
}
}
}
impl From<sqlx::migrate::MigrateError> for StartError {
fn from(value: sqlx::migrate::MigrateError) -> Self {
Self::DatabaseMigrationError {
message: value.to_string(),
}
}
}
#[derive(Debug)]
pub enum CommandError {
UserExists { username: String },
}
impl std::error::Error for CommandError {}
impl fmt::Display for CommandError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::UserExists { username } => {
write!(f, "user \"{username}\" already exists")
}
}
}
}