Files
narlblog/backend/src/error.rs
T
2026-05-16 23:48:57 +02:00

56 lines
1.6 KiB
Rust

use axum::{
Json,
http::StatusCode,
response::{IntoResponse, Response},
};
use tracing::error;
use crate::models::ErrorResponse;
#[derive(Debug)]
pub enum AppError {
Unauthorized,
NotFound(String),
BadRequest(String),
TooManyRequests(String),
/// (public_message, internal_details) — details are logged but not returned.
Internal(String, Option<String>),
}
impl IntoResponse for AppError {
fn into_response(self) -> Response {
let (status, error_message) = match self {
AppError::Unauthorized => (StatusCode::UNAUTHORIZED, "Unauthorized".to_string()),
AppError::NotFound(msg) => (StatusCode::NOT_FOUND, msg),
AppError::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg),
AppError::TooManyRequests(msg) => (StatusCode::TOO_MANY_REQUESTS, msg),
AppError::Internal(msg, details) => {
if let Some(d) = details {
error!("Internal error: {} — {}", msg, d);
} else {
error!("Internal error: {}", msg);
}
(
StatusCode::INTERNAL_SERVER_ERROR,
"Internal error".to_string(),
)
}
};
let body = Json(ErrorResponse {
error: error_message,
});
(status, body).into_response()
}
}
impl<E> From<E> for AppError
where
E: std::error::Error + Send + Sync + 'static,
{
fn from(err: E) -> Self {
AppError::Internal("Internal Server Error".to_string(), Some(err.to_string()))
}
}