102 lines
2.5 KiB
Rust
102 lines
2.5 KiB
Rust
use crate::common::response::AppResponse;
|
|
|
|
#[derive(Debug)]
|
|
pub enum AppErrorType {
|
|
System,
|
|
Config,
|
|
Database,
|
|
Notfound,
|
|
Validate,
|
|
Template,
|
|
Authorization,
|
|
Forbidden,
|
|
}
|
|
|
|
type Cause = Box<dyn std::error::Error>;
|
|
|
|
#[derive(Debug)]
|
|
pub enum AppErrorItem {
|
|
Message(String),
|
|
Cause(Cause),
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct AppError {
|
|
pub types: AppErrorType,
|
|
pub error: AppErrorItem,
|
|
}
|
|
|
|
impl AppError {
|
|
pub fn new(types: AppErrorType, error: AppErrorItem) -> Self {
|
|
Self { types, error }
|
|
}
|
|
pub fn from_err(cause: Cause, types: AppErrorType) -> Self {
|
|
Self::new(types, AppErrorItem::Cause(cause))
|
|
}
|
|
|
|
pub fn from_msg(msg: &str, types: AppErrorType) -> Self {
|
|
Self::new(types, AppErrorItem::Message(msg.to_string()))
|
|
}
|
|
pub fn notfound() -> Self {
|
|
Self::from_msg("不存在的记录", AppErrorType::Notfound)
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Display for AppError {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
let msg = match &self.error {
|
|
AppErrorItem::Cause(err) => err.to_string(),
|
|
AppErrorItem::Message(msg) => msg.to_string(),
|
|
};
|
|
write!(f, "{}", msg)
|
|
}
|
|
}
|
|
|
|
impl std::error::Error for AppError {}
|
|
|
|
impl From<config::ConfigError> for AppError {
|
|
fn from(err: config::ConfigError) -> Self {
|
|
Self::from_err(Box::new(err), AppErrorType::Config)
|
|
}
|
|
}
|
|
|
|
impl From<askama::Error> for AppError {
|
|
fn from(err: askama::Error) -> Self {
|
|
Self::from_err(Box::new(err), AppErrorType::Template)
|
|
}
|
|
}
|
|
|
|
impl From<sea_orm::DbErr> for AppError {
|
|
fn from(err: sea_orm::DbErr) -> Self {
|
|
Self::from_err(Box::new(err), AppErrorType::Database)
|
|
}
|
|
}
|
|
|
|
impl From<jsonwebtoken::errors::Error> for AppError {
|
|
fn from(err: jsonwebtoken::errors::Error) -> Self {
|
|
Self::from_err(Box::new(err), AppErrorType::Authorization)
|
|
}
|
|
}
|
|
|
|
impl From<validator::ValidationErrors> for AppError {
|
|
fn from(err: validator::ValidationErrors) -> Self {
|
|
Self::from_err(Box::new(err), AppErrorType::Validate)
|
|
}
|
|
}
|
|
|
|
|
|
impl axum::response::IntoResponse for AppError {
|
|
fn into_response(self) -> axum::response::Response {
|
|
AppResponse::<()>::from_error(self).into_response()
|
|
}
|
|
}
|
|
|
|
|
|
/// 记录错误
|
|
pub fn log_error(handler_name: &str) -> Box<dyn Fn(AppError) -> AppError> {
|
|
let handler_name = handler_name.to_string();
|
|
Box::new(move |err| {
|
|
tracing::error!("{}: {:?}", handler_name, err);
|
|
err
|
|
})
|
|
} |