use actix_web::{HttpResponse, ResponseError};
use std::fmt;
#[derive(Debug)]
pub struct AppError {
pub status: u16,
pub code: &'static str,
pub message: String,
}
impl AppError {
pub fn new(status: u16, code: &'static str, message: impl Into<String>) -> Self {
Self {
status,
code,
message: message.into(),
}
}
pub fn bad_request(msg: impl Into<String>) -> Self {
Self::new(400, "BAD_REQUEST", msg)
}
pub fn unauthorized(msg: impl Into<String>) -> Self {
Self::new(401, "UNAUTHORIZED", msg)
}
pub fn forbidden(msg: impl Into<String>) -> Self {
Self::new(403, "FORBIDDEN", msg)
}
pub fn not_found(msg: impl Into<String>) -> Self {
Self::new(404, "NOT_FOUND", msg)
}
pub fn conflict(msg: impl Into<String>) -> Self {
Self::new(409, "CONFLICT", msg)
}
pub fn internal(msg: impl Into<String>) -> Self {
Self::new(500, "INTERNAL_ERROR", msg)
}
pub fn server_error(msg: impl Into<String>) -> Self {
Self::new(500, "SERVER_ERROR", msg)
}
}
impl fmt::Display for AppError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}] {}", self.code, self.message)
}
}
impl std::error::Error for AppError {}
impl ResponseError for AppError {
fn error_response(&self) -> HttpResponse {
HttpResponse::build(
actix_web::http::StatusCode::from_u16(self.status)
.unwrap_or(actix_web::http::StatusCode::INTERNAL_SERVER_ERROR),
)
.json(serde_json::json!({
"code": self.code,
"message": self.message,
}))
}
}
pub type AppResult<T> = Result<T, AppError>;