use axum::http::StatusCode; use axum::response::{IntoResponse, Response}; use axum::Json; use serde::Serialize; use thiserror::Error; #[derive(Error, Debug)] pub enum ApiError { #[error("entity not found: {0}")] NotFound(String), #[error("bad request: {0}")] BadRequest(String), #[error("unauthorized")] Unauthorized, #[error("service not registered: {domain}.{service}")] ServiceNotRegistered { domain: String, service: String }, #[error("internal error: {0}")] Internal(String), } pub type ApiResult = Result; #[derive(Serialize)] struct ErrorPayload { message: String } impl IntoResponse for ApiError { fn into_response(self) -> Response { let (status, message) = match &self { Self::NotFound(_) => (StatusCode::NOT_FOUND, self.to_string()), Self::BadRequest(_) => (StatusCode::BAD_REQUEST, self.to_string()), Self::Unauthorized => (StatusCode::UNAUTHORIZED, self.to_string()), Self::ServiceNotRegistered { .. } => (StatusCode::BAD_REQUEST, self.to_string()), Self::Internal(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()), }; (status, Json(ErrorPayload { message })).into_response() } }