use crate::{Response, StatusCode};
use std::backtrace::Backtrace;
use std::io;
use thiserror::Error;
pub type BoxedError = Box<dyn std::error::Error + Send + Sync>;
#[derive(Error, Debug)]
pub enum SilentError {
#[error("io error")]
IOError(#[from] io::Error),
#[error("io error")]
TungsteniteError(#[from] tokio_tungstenite::tungstenite::Error),
#[error("serde_json error `{0}`")]
SerdeJsonError(#[from] serde_json::Error),
#[error("serde de error `{0}`")]
SerdeDeError(#[from] serde::de::value::Error),
#[error("the data for key `{0}` is not available")]
HyperError(#[from] hyper::Error),
#[error("upload file read error `{0}`")]
FileEmpty(#[from] multer::Error),
#[error("body is empty")]
BodyEmpty,
#[error("json is empty")]
JsonEmpty,
#[error("content-type is error")]
ContentTypeError,
#[error("params is empty")]
ParamsEmpty,
#[error("params not found")]
ParamsNotFound,
#[error("websocket error: {0}")]
WsError(String),
#[error("business error: {msg} ({code})")]
BusinessError {
code: StatusCode,
msg: String,
},
}
pub type SilentResult<T> = Result<T, SilentError>;
impl SilentError {
pub fn business_error(code: StatusCode, msg: String) -> Self {
Self::BusinessError { code, msg }
}
pub fn status_code(&self) -> StatusCode {
match self {
Self::IOError(_) => StatusCode::INTERNAL_SERVER_ERROR,
Self::TungsteniteError(_) => StatusCode::INTERNAL_SERVER_ERROR,
Self::SerdeJsonError(_) => StatusCode::INTERNAL_SERVER_ERROR,
Self::SerdeDeError(_) => StatusCode::INTERNAL_SERVER_ERROR,
Self::HyperError(_) => StatusCode::INTERNAL_SERVER_ERROR,
Self::FileEmpty(_) => StatusCode::INTERNAL_SERVER_ERROR,
Self::BodyEmpty => StatusCode::INTERNAL_SERVER_ERROR,
Self::JsonEmpty => StatusCode::INTERNAL_SERVER_ERROR,
Self::ContentTypeError => StatusCode::INTERNAL_SERVER_ERROR,
Self::ParamsEmpty => StatusCode::INTERNAL_SERVER_ERROR,
Self::ParamsNotFound => StatusCode::INTERNAL_SERVER_ERROR,
Self::WsError(_) => StatusCode::INTERNAL_SERVER_ERROR,
Self::BusinessError { code, .. } => *code,
}
}
pub fn trace(&self) -> Backtrace {
Backtrace::capture()
}
}
impl From<SilentError> for Response {
fn from(value: SilentError) -> Self {
let mut res = Response::empty();
res.set_status(value.status_code());
res.set_body(value.to_string().into());
res
}
}