nekrochan/src/error.rs

234 řádky
8.1 KiB
Rust
Spustitelný soubor

use actix_web::{http::StatusCode, ResponseError};
use log::error;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum NekrochanError {
#[error("Chyba při zpracovávání souboru '{}': {}", .0, .1)]
FileError(String, &'static str),
#[error("Uživatelské jméno musí mít 1-32 znaků.")]
UsernameFormatError,
#[error("Heslo musí mít alespoň 8 znaků.")]
PasswordFormatError,
#[error("ID musí mít 1-16 znaků.")]
IdFormatError,
#[error("Jméno nástěnky musí mít 1-32 znaků.")]
BoardNameFormatError,
#[error("Popis musí mít 1-128 znaků.")]
DescriptionFormatError,
#[error("Jméno nesmí mít více než 32 znaků.")]
PostNameFormatError,
#[error("Capcode nesmí mít více než 32 znaků.")]
CapcodeFormatError,
#[error("E-mail nesmí mít více než 256 znaků.")]
EmailFormatError,
#[error("Obsah nesmí mít více než 4000 znaků")]
ContentFormatError,
#[error("Nástěnka /{}/ neexistuje.", .0)]
BoardNotFound(String),
#[error("Účet '{}' neexistuje.", .0)]
AccountNotFound(String),
#[error("Příspěvek /{}/{} neexistuje.", .0, .1)]
PostNotFound(String, i32),
#[error("Nedostatečná oprávnění.")]
InsufficientPermissionError,
#[error("Nesprávné přihlašovací údaje.")]
IncorrectCredentialError,
#[error("Neplatná strana.")]
InvalidPageError,
#[error("Neplatný autentizační token. Vymaž soubory cookie.")]
InvalidAuthError,
#[error("Pro přístup se musíš přihlásit.")]
NotLoggedInError,
#[error("Účet vlastníka nemůže být vymazán.")]
OwnerDeletionError,
#[error("Reverzní proxy nevrátilo vyžadovanou hlavičku '{}'.", .0)]
HeaderError(&'static str),
#[error("Nástěnka /{}/ je uzamčená.", .0)]
BoardLockError(String),
#[error("Toto vlákno je uzamčené.")]
ThreadLockError,
#[error("Nelze vytvořit odpověď na odpověď.")]
ReplyReplyError,
#[error("Vlákno dosáhlo limitu odpovědí.")]
ReplyLimitError,
#[error("Příspěvek musí mít obsah.")]
NoContentError,
#[error("Příspěvek musí mít soubor.")]
NoFileError,
#[error("Příspěvek musí mít obsah nebo soubor.")]
EmptyPostError,
#[error("Na této nástěnce se musí vyplnit CAPTCHA.")]
RequiredCaptchaError,
#[error("Nesprávné řešení CAPTCHA.")]
IncorrectCaptchaError,
#[error("Tato CAPTCHA neexistuje nebo už byla vyřešena.")]
SolvedCaptchaError,
#[error("Nebyly vybrány žádné příspěvky.")]
NoPostsError,
#[error("Maximální počet souborů na této nástěnce je {}.", .0)]
FileLimitError(usize),
#[error("Nesprávné heslo pro příspěvek #{}.", .0)]
IncorrectPasswordError(i32),
// 500
#[error("Nadnástěnka nebyla inicializována.")]
OverboardError,
#[error("Server se připojil k 41 procentům.")]
InternalError,
}
impl From<askama::Error> for NekrochanError {
fn from(e: askama::Error) -> Self {
error!("Internal server error: {e:#?}");
Self::InternalError
}
}
impl From<ipnetwork::IpNetworkError> for NekrochanError {
fn from(e: ipnetwork::IpNetworkError) -> Self {
error!("Internal server error: {e:#?}");
Self::InternalError
}
}
impl From<jsonwebtoken::errors::Error> for NekrochanError {
fn from(e: jsonwebtoken::errors::Error) -> Self {
error!("Internal server error: {e:#?}");
Self::InternalError
}
}
impl From<pwhash::error::Error> for NekrochanError {
fn from(e: pwhash::error::Error) -> Self {
error!("Internal server error: {e:#?}");
Self::InternalError
}
}
impl From<fancy_regex::Error> for NekrochanError {
fn from(e: fancy_regex::Error) -> Self {
error!("Internal server error: {e:#?}");
Self::InternalError
}
}
impl From<redis::RedisError> for NekrochanError {
fn from(e: redis::RedisError) -> Self {
error!("Internal server error: {e:#?}");
Self::InternalError
}
}
impl From<serde_json::Error> for NekrochanError {
fn from(e: serde_json::Error) -> Self {
error!("Internal server error: {e:#?}");
Self::InternalError
}
}
impl From<serde_qs::Error> for NekrochanError {
fn from(e: serde_qs::Error) -> Self {
error!("Internal server error: {e:#?}");
Self::InternalError
}
}
impl From<sqlx::Error> for NekrochanError {
fn from(e: sqlx::Error) -> Self {
let overboard_err = match e.as_database_error() {
Some(e) => e.message() == "relation \"overboard\" does not exist",
None => false,
};
if !overboard_err {
error!("{e:#?}");
Self::InternalError
} else {
Self::OverboardError
}
}
}
impl From<std::io::Error> for NekrochanError {
fn from(e: std::io::Error) -> Self {
error!("Internal server error: {e:#?}");
Self::InternalError
}
}
impl From<std::net::AddrParseError> for NekrochanError {
fn from(e: std::net::AddrParseError) -> Self {
error!("Internal server error: {e:#?}");
Self::InternalError
}
}
impl<T> From<std::sync::PoisonError<T>> for NekrochanError {
fn from(_: std::sync::PoisonError<T>) -> Self {
error!("CAPTCHA RwLock got poisoned or something.");
Self::InternalError
}
}
impl From<tokio::task::JoinError> for NekrochanError {
fn from(e: tokio::task::JoinError) -> Self {
error!("Internal server error: {e:#?}");
Self::InternalError
}
}
impl ResponseError for NekrochanError {
fn status_code(&self) -> StatusCode {
match self {
NekrochanError::FileError(_, _) => StatusCode::BAD_REQUEST,
NekrochanError::UsernameFormatError => StatusCode::BAD_REQUEST,
NekrochanError::PasswordFormatError => StatusCode::BAD_REQUEST,
NekrochanError::IdFormatError => StatusCode::BAD_REQUEST,
NekrochanError::BoardNameFormatError => StatusCode::BAD_REQUEST,
NekrochanError::DescriptionFormatError => StatusCode::BAD_REQUEST,
NekrochanError::PostNameFormatError => StatusCode::BAD_REQUEST,
NekrochanError::CapcodeFormatError => StatusCode::BAD_REQUEST,
NekrochanError::EmailFormatError => StatusCode::BAD_REQUEST,
NekrochanError::ContentFormatError => StatusCode::BAD_REQUEST,
NekrochanError::BoardNotFound(_) => StatusCode::NOT_FOUND,
NekrochanError::AccountNotFound(_) => StatusCode::NOT_FOUND,
NekrochanError::PostNotFound(_, _) => StatusCode::NOT_FOUND,
NekrochanError::InsufficientPermissionError => StatusCode::FORBIDDEN,
NekrochanError::IncorrectCredentialError => StatusCode::UNAUTHORIZED,
NekrochanError::InvalidPageError => StatusCode::NOT_FOUND,
NekrochanError::InvalidAuthError => StatusCode::NOT_FOUND,
NekrochanError::NotLoggedInError => StatusCode::UNAUTHORIZED,
NekrochanError::OwnerDeletionError => StatusCode::FORBIDDEN,
NekrochanError::HeaderError(_) => StatusCode::BAD_GATEWAY,
NekrochanError::BoardLockError(_) => StatusCode::FORBIDDEN,
NekrochanError::ThreadLockError => StatusCode::FORBIDDEN,
NekrochanError::ReplyReplyError => StatusCode::BAD_REQUEST,
NekrochanError::ReplyLimitError => StatusCode::FORBIDDEN,
NekrochanError::NoContentError => StatusCode::BAD_REQUEST,
NekrochanError::NoFileError => StatusCode::BAD_REQUEST,
NekrochanError::EmptyPostError => StatusCode::BAD_REQUEST,
NekrochanError::RequiredCaptchaError => StatusCode::BAD_REQUEST,
NekrochanError::IncorrectCaptchaError => StatusCode::UNAUTHORIZED,
NekrochanError::SolvedCaptchaError => StatusCode::BAD_REQUEST,
NekrochanError::NoPostsError => StatusCode::BAD_REQUEST,
NekrochanError::FileLimitError(_) => StatusCode::BAD_REQUEST,
NekrochanError::IncorrectPasswordError(_) => StatusCode::UNAUTHORIZED,
NekrochanError::OverboardError => StatusCode::INTERNAL_SERVER_ERROR,
NekrochanError::InternalError => StatusCode::INTERNAL_SERVER_ERROR,
}
}
}