81 lines
2.3 KiB
Rust
81 lines
2.3 KiB
Rust
use axum::http::StatusCode;
|
|
use axum::response::{IntoResponse, Response};
|
|
use serde_json::json;
|
|
use thiserror::Error;
|
|
|
|
#[derive(Debug, Error)]
|
|
pub enum ApiError {
|
|
#[error("Database error: {0}")]
|
|
Database(#[from] sea_orm::DbErr),
|
|
|
|
#[error("Validation error: {0}")]
|
|
Validation(String),
|
|
|
|
#[error("Not found: {0}")]
|
|
NotFound(String),
|
|
|
|
#[error("Bad request: {0}")]
|
|
BadRequest(String),
|
|
|
|
#[error("Internal server error: {0}")]
|
|
Internal(String),
|
|
|
|
#[error("Unauthorized: {0}")]
|
|
Unauthorized(String),
|
|
|
|
#[error("Forbidden: {0}")]
|
|
Forbidden(String),
|
|
}
|
|
|
|
impl IntoResponse for ApiError {
|
|
fn into_response(self) -> Response {
|
|
let (status, error_message) = match self {
|
|
ApiError::Database(err) => (
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
format!("Database error: {}", err),
|
|
),
|
|
ApiError::Validation(msg) => (StatusCode::BAD_REQUEST, msg),
|
|
ApiError::NotFound(msg) => (StatusCode::NOT_FOUND, msg),
|
|
ApiError::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg),
|
|
ApiError::Internal(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg),
|
|
ApiError::Unauthorized(msg) => (StatusCode::UNAUTHORIZED, msg),
|
|
ApiError::Forbidden(msg) => (StatusCode::FORBIDDEN, msg),
|
|
};
|
|
|
|
let body = json!({
|
|
"error": {
|
|
"code": status.as_u16(),
|
|
"message": error_message
|
|
}
|
|
});
|
|
|
|
(status, axum::Json(body)).into_response()
|
|
}
|
|
}
|
|
|
|
pub type ApiResult<T> = Result<T, ApiError>;
|
|
|
|
impl From<validator::ValidationErrors> for ApiError {
|
|
fn from(err: validator::ValidationErrors) -> Self {
|
|
let errors: Vec<String> = err
|
|
.field_errors()
|
|
.iter()
|
|
.map(|(field, errors)| {
|
|
let error_msgs: Vec<String> = errors
|
|
.iter()
|
|
.map(|error| {
|
|
if let Some(msg) = &error.message {
|
|
msg.to_string()
|
|
} else {
|
|
format!("Validation failed for field: {}", field)
|
|
}
|
|
})
|
|
.collect();
|
|
error_msgs.join(", ")
|
|
})
|
|
.collect();
|
|
|
|
ApiError::Validation(errors.join("; "))
|
|
}
|
|
}
|