Skip to main content

ph_registry/
error.rs

1use axum::{http::StatusCode, response::{IntoResponse, Response}, Json};
2use serde_json::json;
3use thiserror::Error;
4
5#[derive(Error, Debug)]
6pub enum RegistryError {
7    #[error("unauthorized")]
8    Unauthorized,
9
10    #[error("layer not found: {0}")]
11    NotFound(String),
12
13    #[error("version already exists: {0}")]
14    Conflict(String),
15
16    #[error("bad request: {0}")]
17    BadRequest(String),
18
19    #[error("database error: {0}")]
20    Database(#[from] rusqlite::Error),
21
22    #[error("storage error: {0}")]
23    Storage(String),
24
25    #[error("internal error: {0}")]
26    Internal(String),
27}
28
29impl IntoResponse for RegistryError {
30    fn into_response(self) -> Response {
31        let (status, message) = match &self {
32            RegistryError::Unauthorized     => (StatusCode::UNAUTHORIZED, self.to_string()),
33            RegistryError::NotFound(_)      => (StatusCode::NOT_FOUND, self.to_string()),
34            RegistryError::Conflict(_)      => (StatusCode::CONFLICT, self.to_string()),
35            RegistryError::BadRequest(_)    => (StatusCode::BAD_REQUEST, self.to_string()),
36            RegistryError::Database(e)      => {
37                tracing::error!("database error: {}", e);
38                (StatusCode::INTERNAL_SERVER_ERROR, "internal error".to_string())
39            }
40            RegistryError::Storage(msg)     => {
41                tracing::error!("storage error: {}", msg);
42                (StatusCode::INTERNAL_SERVER_ERROR, "storage error".to_string())
43            }
44            RegistryError::Internal(msg)    => {
45                tracing::error!("internal error: {}", msg);
46                (StatusCode::INTERNAL_SERVER_ERROR, "internal error".to_string())
47            }
48        };
49        (status, Json(json!({"error": message}))).into_response()
50    }
51}
52
53pub type Result<T> = std::result::Result<T, RegistryError>;