use axum::{
Json,
http::StatusCode,
response::{IntoResponse, Response},
};
use crate::api::models::ErrorResponse;
#[derive(Debug)]
pub struct ApiError {
pub status: StatusCode,
pub code: &'static str,
pub message: String,
}
impl ApiError {
pub fn new(status: StatusCode, code: &'static str, message: impl Into<String>) -> Self {
Self {
status,
code,
message: message.into(),
}
}
pub fn bad_request(message: impl Into<String>) -> Self {
Self::new(StatusCode::BAD_REQUEST, "bad_request", message)
}
pub fn payload_too_large(message: impl Into<String>) -> Self {
Self::new(StatusCode::PAYLOAD_TOO_LARGE, "payload_too_large", message)
}
pub fn not_found(message: impl Into<String>) -> Self {
Self::new(StatusCode::NOT_FOUND, "not_found", message)
}
pub fn conflict(message: impl Into<String>) -> Self {
Self::new(StatusCode::CONFLICT, "conflict", message)
}
pub fn service_unavailable(message: impl Into<String>) -> Self {
Self::new(
StatusCode::SERVICE_UNAVAILABLE,
"service_unavailable",
message,
)
}
pub fn internal(message: impl Into<String>) -> Self {
Self::new(
StatusCode::INTERNAL_SERVER_ERROR,
"internal_server_error",
message,
)
}
}
impl IntoResponse for ApiError {
fn into_response(self) -> Response {
(
self.status,
Json(ErrorResponse {
code: self.code.to_string(),
message: self.message,
details: None,
}),
)
.into_response()
}
}
impl From<anyhow::Error> for ApiError {
fn from(value: anyhow::Error) -> Self {
Self::internal(format!("{value:#}"))
}
}