Platform restructured into crates/, added AI service and detector,
migrated control-center-ui to Leptos 0.8
105 lines
2.8 KiB
Rust
105 lines
2.8 KiB
Rust
use std::fmt;
|
|
|
|
use axum::http::StatusCode;
|
|
use axum::response::{IntoResponse, Response};
|
|
|
|
/// Registry error types
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum RegistryError {
|
|
#[error("Extension not found: {0}")]
|
|
NotFound(String),
|
|
|
|
#[error("Invalid extension type: {0}")]
|
|
InvalidType(String),
|
|
|
|
#[error("Invalid version format: {0}")]
|
|
InvalidVersion(String),
|
|
|
|
#[error("Gitea API error: {0}")]
|
|
Gitea(String),
|
|
|
|
#[error("Forgejo API error: {0}")]
|
|
Forgejo(String),
|
|
|
|
#[error("GitHub API error: {0}")]
|
|
Github(String),
|
|
|
|
#[error("OCI registry error: {0}")]
|
|
Oci(String),
|
|
|
|
#[error("Cache error: {0}")]
|
|
Cache(String),
|
|
|
|
#[error("HTTP request error: {0}")]
|
|
Http(#[from] reqwest::Error),
|
|
|
|
#[error("IO error: {0}")]
|
|
Io(#[from] std::io::Error),
|
|
|
|
#[error("JSON serialization error: {0}")]
|
|
Json(#[from] serde_json::Error),
|
|
|
|
#[error("Configuration error: {0}")]
|
|
Config(String),
|
|
|
|
#[error("Authentication error: {0}")]
|
|
Auth(String),
|
|
|
|
#[error("Rate limit exceeded")]
|
|
RateLimit,
|
|
|
|
#[error("No backends configured")]
|
|
NoBackendsConfigured,
|
|
|
|
#[error("All backends failed: {0}")]
|
|
MultiBackendFailure(String),
|
|
|
|
#[error("Internal server error: {0}")]
|
|
Internal(String),
|
|
}
|
|
|
|
/// Result type alias
|
|
pub type Result<T> = std::result::Result<T, RegistryError>;
|
|
|
|
/// API error response
|
|
#[derive(Debug, serde::Serialize)]
|
|
pub struct ApiErrorResponse {
|
|
pub error: String,
|
|
pub message: String,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub details: Option<String>,
|
|
}
|
|
|
|
impl IntoResponse for RegistryError {
|
|
fn into_response(self) -> Response {
|
|
let (status, error_type) = match &self {
|
|
RegistryError::NotFound(_) => (StatusCode::NOT_FOUND, "not_found"),
|
|
RegistryError::InvalidType(_) => (StatusCode::BAD_REQUEST, "invalid_type"),
|
|
RegistryError::InvalidVersion(_) => (StatusCode::BAD_REQUEST, "invalid_version"),
|
|
RegistryError::Auth(_) => (StatusCode::UNAUTHORIZED, "auth_error"),
|
|
RegistryError::RateLimit => (StatusCode::TOO_MANY_REQUESTS, "rate_limit"),
|
|
RegistryError::Config(_) | RegistryError::NoBackendsConfigured => {
|
|
(StatusCode::INTERNAL_SERVER_ERROR, "config_error")
|
|
}
|
|
RegistryError::MultiBackendFailure(_) => {
|
|
(StatusCode::SERVICE_UNAVAILABLE, "backend_failure")
|
|
}
|
|
_ => (StatusCode::INTERNAL_SERVER_ERROR, "internal_error"),
|
|
};
|
|
|
|
let body = ApiErrorResponse {
|
|
error: error_type.to_string(),
|
|
message: self.to_string(),
|
|
details: None,
|
|
};
|
|
|
|
(status, axum::Json(body)).into_response()
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for ApiErrorResponse {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "{}: {}", self.error, self.message)
|
|
}
|
|
}
|