1use axum::{
2 http::StatusCode,
3 response::{IntoResponse, Response},
4 Json,
5};
6use minifly_core::Error as CoreError;
7use serde_json::json;
8
9pub struct ApiError(pub CoreError);
10
11impl From<CoreError> for ApiError {
12 fn from(err: CoreError) -> Self {
13 ApiError(err)
14 }
15}
16
17impl From<anyhow::Error> for ApiError {
18 fn from(err: anyhow::Error) -> Self {
19 ApiError(CoreError::Internal(err.to_string()))
20 }
21}
22
23impl IntoResponse for ApiError {
24 fn into_response(self) -> Response {
25 let (status, error_message) = match self.0 {
26 CoreError::MachineNotFound(ref id) => (StatusCode::NOT_FOUND, format!("Machine not found: {}", id)),
27 CoreError::AppNotFound(ref name) => (StatusCode::NOT_FOUND, format!("App not found: {}", name)),
28 CoreError::NotFound => (StatusCode::NOT_FOUND, "Resource not found".to_string()),
29 CoreError::InvalidConfiguration(ref msg) => (StatusCode::BAD_REQUEST, format!("Invalid configuration: {}", msg)),
30 CoreError::BadRequest(ref msg) => (StatusCode::BAD_REQUEST, msg.clone()),
31 CoreError::AuthenticationFailed => (StatusCode::UNAUTHORIZED, "Authentication failed".to_string()),
32 CoreError::LeaseConflict => (StatusCode::CONFLICT, "Lease conflict".to_string()),
33 CoreError::InvalidLeaseNonce => (StatusCode::BAD_REQUEST, "Invalid lease nonce".to_string()),
34 CoreError::DockerError(ref msg) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Docker error: {}", msg)),
35 CoreError::DatabaseError(ref msg) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Database error: {}", msg)),
36 CoreError::NetworkError(ref msg) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Network error: {}", msg)),
37 CoreError::Internal(ref msg) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Internal error: {}", msg)),
38 CoreError::LiteFSError(ref msg) => (StatusCode::INTERNAL_SERVER_ERROR, format!("LiteFS error: {}", msg)),
39 CoreError::Anyhow(ref err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Internal error: {}", err)),
40 };
41
42 let body = Json(json!({
43 "error": error_message,
44 }));
45
46 (status, body).into_response()
47 }
48}
49
50pub type Result<T> = std::result::Result<T, ApiError>;