common/emgauwa-core/src/handlers/errors.rs

83 lines
2 KiB
Rust

use std::fmt::{Display, Formatter};
use actix_web::http::StatusCode;
use actix_web::HttpResponse;
use emgauwa_lib::db::errors::DatabaseError;
use serde::ser::SerializeStruct;
use serde::{Serialize, Serializer};
#[derive(Debug)]
pub enum ApiError {
BadUid,
ProtectedSchedule,
DatabaseError(DatabaseError),
InternalError(String),
}
impl ApiError {
fn get_code(&self) -> StatusCode {
match self {
ApiError::BadUid => StatusCode::BAD_REQUEST,
ApiError::ProtectedSchedule => StatusCode::FORBIDDEN,
ApiError::DatabaseError(db_error) => db_error.get_code(),
ApiError::InternalError(_) => StatusCode::INTERNAL_SERVER_ERROR,
}
}
}
impl Serialize for ApiError {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut s = serializer.serialize_struct("error", 2)?;
s.serialize_field("code", &self.get_code().as_u16())?;
s.serialize_field("description", &String::from(self))?;
s.end()
}
}
impl From<&ApiError> for String {
fn from(err: &ApiError) -> Self {
match err {
ApiError::BadUid => String::from("the uid is in a bad format"),
ApiError::ProtectedSchedule => String::from("the targeted schedule is protected"),
ApiError::DatabaseError(db_err) => String::from(db_err),
ApiError::InternalError(msg) => msg.clone(),
}
}
}
impl From<&ApiError> for HttpResponse {
fn from(err: &ApiError) -> Self {
HttpResponse::build(err.get_code()).json(err)
}
}
impl Display for ApiError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}: {}", self.get_code(), String::from(self))
}
}
impl actix_web::error::ResponseError for ApiError {
fn status_code(&self) -> StatusCode {
self.get_code()
}
fn error_response(&self) -> HttpResponse {
HttpResponse::from(self)
}
}
impl From<sqlx::Error> for ApiError {
fn from(err: sqlx::Error) -> Self {
ApiError::DatabaseError(DatabaseError::from(err))
}
}
impl From<DatabaseError> for ApiError {
fn from(err: DatabaseError) -> Self {
ApiError::DatabaseError(err)
}
}