Skip to content
Clone
b90f48e
80 lines 2.5 KB Rust
use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
#[derive(Debug, thiserror::Error)]
pub enum SmartError {
#[error("{0}")]
BadRequest(String),
#[error("unauthorized")]
Unauthorized,
#[error("{0}")]
Forbidden(String),
#[error("{0}")]
NotFound(String),
#[error("{0}")]
Conflict(String),
#[error("{0}")]
Internal(String),
#[error("io error: {0}")]
Io(#[from] std::io::Error),
#[error("database error: {0}")]
Db(#[from] sea_orm::DbErr),
#[error("redis error: {0}")]
Redis(#[from] redis::RedisError),
}
pub type SmartResult<T> = Result<T, SmartError>;
impl SmartError {
pub fn status(&self) -> StatusCode {
match self {
Self::BadRequest(_) => StatusCode::BAD_REQUEST,
Self::Unauthorized => StatusCode::UNAUTHORIZED,
Self::Forbidden(_) => StatusCode::FORBIDDEN,
Self::NotFound(_) => StatusCode::NOT_FOUND,
Self::Conflict(_) => StatusCode::CONFLICT,
_ => StatusCode::INTERNAL_SERVER_ERROR,
}
}
pub fn message(&self) -> String {
match self {
Self::BadRequest(m) | Self::Forbidden(m) | Self::NotFound(m) | Self::Conflict(m) => {
m.clone()
}
Self::Internal(m) => {
tracing::warn!(error = %m, "smart http internal error");
"internal server error".to_string()
}
other => other.to_string(),
}
}
}
impl From<crate::share::errors::GitError> for SmartError {
fn from(err: crate::share::errors::GitError) -> Self {
use crate::share::errors::GitError;
match err {
GitError::Unauthorized => Self::Unauthorized,
GitError::NotFound => Self::NotFound("resource not found".into()),
GitError::Forbidden => Self::Forbidden("forbidden".into()),
GitError::InvalidArgument(m) => Self::BadRequest(m),
GitError::Conflict(m) => Self::Conflict(m),
other => Self::Internal(other.to_string()),
}
}
}
impl IntoResponse for SmartError {
fn into_response(self) -> Response {
let status = self.status();
let mut resp = (status, self.message()).into_response();
if status == StatusCode::UNAUTHORIZED {
resp.headers_mut().insert(
axum::http::header::WWW_AUTHENTICATE,
axum::http::HeaderValue::from_static("Basic realm=\"gitdata\""),
);
}
resp
}
}