core: move errors to separate module

This commit is contained in:
anna 2023-01-19 12:43:57 +01:00
parent 64739eeead
commit 20b5cc32cc
Signed by: fef
GPG key ID: EC22E476DC2D3D84
2 changed files with 117 additions and 112 deletions

114
src/core/error.rs Normal file
View file

@ -0,0 +1,114 @@
use actix_web::{
body::BoxBody,
http::{header, StatusCode},
HttpResponse, ResponseError,
};
use serde::{ser::SerializeMap, Serialize, Serializer};
use std::{fmt, io};
use crate::util::validate;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
pub enum Error {
BadBearcap,
BadCredentials,
BadRequest,
BadToken(jsonwebtoken::errors::Error),
Database(sqlx::Error),
Invalid(validate::Error),
Io(io::Error),
MalformedApub(String),
MalformedHeader(header::ToStrError),
NotFound,
Reqwest(reqwest::Error),
}
impl ResponseError for Error {
fn status_code(&self) -> StatusCode {
match self {
Error::BadBearcap => StatusCode::UNPROCESSABLE_ENTITY,
Error::BadCredentials => StatusCode::UNAUTHORIZED,
Error::BadRequest => StatusCode::BAD_REQUEST,
Error::BadToken(_) => StatusCode::UNAUTHORIZED,
Error::Invalid(_) => StatusCode::UNPROCESSABLE_ENTITY,
Error::MalformedApub(_) => StatusCode::UNPROCESSABLE_ENTITY,
Error::MalformedHeader(_) => StatusCode::BAD_REQUEST,
Error::NotFound => StatusCode::NOT_FOUND,
_ => StatusCode::INTERNAL_SERVER_ERROR,
}
}
fn error_response(&self) -> HttpResponse<BoxBody> {
HttpResponse::build(self.status_code()).json(self)
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::BadBearcap => write!(f, "Invalid bearcap URL"),
Error::BadCredentials => write!(f, "Invalid user name or password"),
Error::BadRequest => write!(f, "Bad request"),
Error::BadToken(jwt_error) => jwt_error.fmt(f),
Error::Database(sqlx_error) => sqlx_error.fmt(f),
Error::Invalid(validate_error) => validate_error.fmt(f),
Error::Io(io_error) => io_error.fmt(f),
Error::NotFound => write!(f, "Not found"),
Error::MalformedApub(msg) => write!(f, "Malformed ActivityPub: {msg}"),
Error::MalformedHeader(to_str_error) => to_str_error.fmt(f),
Error::Reqwest(reqwest_error) => reqwest_error.fmt(f),
}
}
}
impl From<sqlx::Error> for Error {
fn from(e: sqlx::Error) -> Error {
match e {
sqlx::Error::RowNotFound => Error::NotFound,
_ => Error::Database(e),
}
}
}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Error {
Error::Io(e)
}
}
impl From<validate::Error> for Error {
fn from(e: validate::Error) -> Error {
Error::Invalid(e)
}
}
impl From<header::ToStrError> for Error {
fn from(e: header::ToStrError) -> Error {
Error::MalformedHeader(e)
}
}
impl From<jsonwebtoken::errors::Error> for Error {
fn from(e: jsonwebtoken::errors::Error) -> Error {
Error::BadToken(e)
}
}
impl From<reqwest::Error> for Error {
fn from(e: reqwest::Error) -> Error {
Error::Reqwest(e)
}
}
impl Serialize for Error {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut fields = serializer.serialize_map(Some(1))?;
fields.serialize_entry("msg", format!("{}", self).as_str())?;
fields.end()
}
}

View file

@ -1,36 +1,15 @@
use actix_web::body::BoxBody;
use actix_web::http::{header, StatusCode};
use actix_web::{HttpResponse, ResponseError};
use chrono::prelude::*;
use serde::{Serialize, Serializer};
use std::time::{SystemTime, UNIX_EPOCH};
use std::{fmt, io};
use crate::util::validate;
pub use log::{debug, error, info, trace, warn};
use serde::ser::SerializeMap;
pub use crate::util::validate::{Insane, Sane};
mod error;
pub use error::*;
pub type Id = i64;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
pub enum Error {
Database(sqlx::Error),
Io(io::Error),
NotFound,
Invalid(validate::Error),
MalformedHeader(header::ToStrError),
BadToken(jsonwebtoken::errors::Error),
BadCredentials,
BadBearcap,
BadRequest,
MalformedApub(String),
Reqwest(reqwest::Error),
}
pub fn utc_now() -> NaiveDateTime {
Utc::now().naive_utc()
}
@ -41,91 +20,3 @@ pub fn unix_now() -> i64 {
.expect("You've either broken spacetime, or your system clock is a bit off.")
.as_secs() as i64
}
impl ResponseError for Error {
fn status_code(&self) -> StatusCode {
match self {
Error::NotFound => StatusCode::NOT_FOUND,
Error::Invalid(_) => StatusCode::UNPROCESSABLE_ENTITY,
Error::MalformedHeader(_) => StatusCode::BAD_REQUEST,
Error::BadToken(_) => StatusCode::UNAUTHORIZED,
Error::BadCredentials => StatusCode::UNAUTHORIZED,
Error::BadBearcap => StatusCode::UNPROCESSABLE_ENTITY,
Error::BadRequest => StatusCode::BAD_REQUEST,
Error::MalformedApub(_) => StatusCode::UNPROCESSABLE_ENTITY,
_ => StatusCode::INTERNAL_SERVER_ERROR,
}
}
fn error_response(&self) -> HttpResponse<BoxBody> {
HttpResponse::build(self.status_code()).json(self)
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Database(sqlx_error) => sqlx_error.fmt(f),
Error::Io(io_error) => io_error.fmt(f),
Error::NotFound => write!(f, "Not found"),
Error::Invalid(validate_error) => validate_error.fmt(f),
Error::MalformedHeader(to_str_error) => to_str_error.fmt(f),
Error::BadToken(jwt_error) => jwt_error.fmt(f),
Error::BadCredentials => write!(f, "Invalid user name or password"),
Error::BadBearcap => write!(f, "Invalid bearcap URL"),
Error::BadRequest => write!(f, "Bad request"),
Error::MalformedApub(msg) => write!(f, "Malformed ActivityPub: {msg}"),
Error::Reqwest(reqwest_error) => reqwest_error.fmt(f),
}
}
}
impl From<sqlx::Error> for Error {
fn from(e: sqlx::Error) -> Error {
match e {
sqlx::Error::RowNotFound => Error::NotFound,
_ => Error::Database(e),
}
}
}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Error {
Error::Io(e)
}
}
impl From<validate::Error> for Error {
fn from(e: validate::Error) -> Error {
Error::Invalid(e)
}
}
impl From<header::ToStrError> for Error {
fn from(e: header::ToStrError) -> Error {
Error::MalformedHeader(e)
}
}
impl From<jsonwebtoken::errors::Error> for Error {
fn from(e: jsonwebtoken::errors::Error) -> Error {
Error::BadToken(e)
}
}
impl From<reqwest::Error> for Error {
fn from(e: reqwest::Error) -> Error {
Error::Reqwest(e)
}
}
impl Serialize for Error {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut fields = serializer.serialize_map(Some(1))?;
fields.serialize_entry("msg", format!("{}", self).as_str())?;
fields.end()
}
}