Skip to main content

chamber_api/
error.rs

1use axum::Json;
2use axum::http::StatusCode;
3use axum::response::{IntoResponse, Response};
4use color_eyre::eyre::Error;
5use serde_json::json;
6pub type ApiResult<T> = Result<T, ApiError>;
7
8#[derive(Debug)]
9pub enum ApiError {
10    Unauthorized,
11    Forbidden,
12    NotFound(String),
13    BadRequest(String),
14    InternalError(String),
15    VaultError(String),
16    ValidationError(String),
17}
18
19impl IntoResponse for ApiError {
20    fn into_response(self) -> Response {
21        let (status, code, message) = match self {
22            ApiError::Unauthorized => (
23                StatusCode::UNAUTHORIZED,
24                "UNAUTHORIZED",
25                String::from("Authentication required"),
26            ),
27            ApiError::Forbidden => (StatusCode::FORBIDDEN, "FORBIDDEN", String::from("Access denied")),
28            ApiError::NotFound(msg) => (StatusCode::NOT_FOUND, "NOT_FOUND", msg),
29            ApiError::BadRequest(msg) => (StatusCode::BAD_REQUEST, "BAD_REQUEST", msg),
30            ApiError::InternalError(msg) => (StatusCode::INTERNAL_SERVER_ERROR, "INTERNAL_ERROR", msg),
31            ApiError::VaultError(msg) => (StatusCode::BAD_REQUEST, "VAULT_ERROR", msg),
32            ApiError::ValidationError(msg) => (StatusCode::UNPROCESSABLE_ENTITY, "VALIDATION_ERROR", msg),
33        };
34
35        let body = Json(json!({
36            "error": {
37                "code": code,
38                "message": message.as_str()
39            }
40        }));
41
42        (status, body).into_response()
43    }
44}
45
46impl From<Error> for ApiError {
47    fn from(err: Error) -> Self {
48        ApiError::InternalError(err.to_string())
49    }
50}