38 lines
1.2 KiB
Rust
38 lines
1.2 KiB
Rust
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<T> = Result<T, ApiError>;
|
|
|
|
#[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()
|
|
}
|
|
}
|