use actix_web::{http::StatusCode, HttpResponse, ResponseError};
use crate::core::R;
pub const UNAUTH_ACCESS: u16 = 401;
pub const INVALID_PARAMS: u16 = 413;
pub const INVALID_REQUEST: u16 = 400;
pub const NOT_FOUND_CODE: u16 = 404;
pub const INTERNAL_SERVER_ERROR: u16 = 500;
#[derive(thiserror::Error)]
pub enum Errors {
GenericError(String),
InvalidRequestError(String),
ValidationError(String),
InvalidCredentials(String),
ParseError(String),
SerdeError(serde_json::Error, Option<String>),
JwtError(jsonwebtoken::errors::Error, String),
IOError(String),
DBError(sqlx::Error, String),
EsError(String),
MongoError(anyhow::Error, Option<String>),
HandlebarError(Option<String>),
ActixError(actix_web::error::Error, String),
TungsteniteError(tungstenite::Error, Option<String>),
NotFound(String),
#[error(transparent)]
UnexpectedError(#[from] anyhow::Error),
}
impl ResponseError for Errors {
fn error_response(&self) -> HttpResponse {
let (code, message) = self.error_message();
HttpResponse::build(StatusCode::OK)
.content_type("application/json")
.body(serde_json::to_string(&R::failed(code, message)).unwrap())
}
}
impl std::fmt::Debug for Errors {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
crate::commons::error_chain_fmt(self, f)
}
}
impl std::fmt::Display for Errors {
fn fmt(&self, _: &mut std::fmt::Formatter) -> std::fmt::Result {
Ok(())
}
}
impl Errors {
pub fn error_message(&self) -> (u16, String) {
match self {
Errors::GenericError(msg) => {
log::error!("GenericError: {}", msg);
(INTERNAL_SERVER_ERROR, msg.to_string())
}
Errors::InvalidRequestError(msg) => {
log::error!("InvalidRequestError: {}", msg);
(INVALID_REQUEST, msg.to_string())
}
Errors::ValidationError(msg) => {
log::error!("ValidationError: {}", msg);
(INVALID_REQUEST, msg.to_string())
}
Errors::InvalidCredentials(msg) => {
log::error!("InvalidCredentials: {}", msg);
(INVALID_REQUEST, "InvalidCredentials error".into())
}
Errors::ParseError(msg) => {
log::error!("ParseError: {}", msg);
(INTERNAL_SERVER_ERROR, msg.to_string())
}
Errors::SerdeError(err, msg) => {
if let Some(msg) = msg {
log::error!("SerdeError: error_message={}, error_details={:?}", msg, err);
} else {
log::error!(
"SerdeError: error_message={}, error_details={:?}",
"N/a",
err
);
}
(INTERNAL_SERVER_ERROR, "SerdeError error".into())
}
Errors::JwtError(err, msg) => {
log::warn!("JwtError: error_message={}, error_details={:?}", msg, err);
(UNAUTH_ACCESS, "JwtError error".into())
}
Errors::IOError(msg) => {
log::error!("IOError: {}", msg);
(INTERNAL_SERVER_ERROR, "IOError error".into())
}
Errors::DBError(err, msg) => {
log::error!("DBError: error_message={}, error_details={:?}", msg, err);
(INTERNAL_SERVER_ERROR, "DBError error".into())
}
Errors::EsError(msg) => {
log::error!("EsError: error_message={}", msg);
(INTERNAL_SERVER_ERROR, "EsError error".into())
}
Errors::MongoError(err, msg) => {
if let Some(msg) = msg {
log::error!("MongoError: error_message={}, error_details={:?}", msg, err);
} else {
log::error!(
"MongoError: error_message={}, error_details={:?}",
"N/a",
err
);
}
(INTERNAL_SERVER_ERROR, "MongoError error".into())
}
Errors::HandlebarError(msg) => {
if let Some(msg) = msg {
log::error!("HandlebarError: error_message={}", msg);
} else {
log::error!("HandlebarError: error_message={}", "N/a");
}
(INTERNAL_SERVER_ERROR, "HandlebarError error".into())
}
Errors::ActixError(err, msg) => {
log::error!("ActixError: error_message={}, error_details={:?}", msg, err);
(INTERNAL_SERVER_ERROR, "ActixError error".into())
}
Errors::TungsteniteError(err, msg) => {
if let Some(msg) = msg {
log::error!(
"TungsteniteError: error_message={}, error_details={:?}",
msg,
err
);
} else {
log::error!(
"TungsteniteError: error_message={}, error_details={:?}",
"N/a",
err
);
}
(INTERNAL_SERVER_ERROR, "TungsteniteError error".into())
}
Errors::NotFound(msg) => {
log::warn!("NotFound: {}", msg);
(NOT_FOUND_CODE, "NotFound error".into())
}
Errors::UnexpectedError(error) => {
log::error!("UnexpectedError: error_details={:?}", error);
(
INTERNAL_SERVER_ERROR,
format!("UnexpectedError: error={:?}", error),
)
}
}
}
}
impl From<jsonwebtoken::errors::Error> for Errors {
fn from(err: jsonwebtoken::errors::Error) -> Self {
let msg = err.to_string();
Errors::JwtError(err, msg)
}
}
impl From<actix_web::error::Error> for Errors {
fn from(err: actix_web::error::Error) -> Self {
let msg = err.to_string();
Errors::ActixError(err, msg)
}
}
impl From<sqlx::Error> for Errors {
fn from(err: sqlx::Error) -> Self {
let msg = err.to_string();
Errors::DBError(err, msg)
}
}
impl From<serde_json::Error> for Errors {
fn from(err: serde_json::Error) -> Self {
let msg = err.to_string();
Errors::SerdeError(err, Some(msg))
}
}