70 lines
1.7 KiB
Rust
70 lines
1.7 KiB
Rust
use axum::{
|
|
http::StatusCode,
|
|
response::{IntoResponse, Response},
|
|
Json,
|
|
};
|
|
use serde::Serialize;
|
|
use thiserror::Error;
|
|
|
|
#[derive(Debug, Error)]
|
|
pub enum AppError {
|
|
#[error("{0}")]
|
|
BadRequest(String),
|
|
#[error("{0}")]
|
|
NotFound(String),
|
|
#[error("{0}")]
|
|
Conflict(String),
|
|
#[error("{0}")]
|
|
ServiceUnavailable(String),
|
|
#[error("{0}")]
|
|
Internal(String),
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
struct ErrorResponse {
|
|
code: &'static str,
|
|
message: String,
|
|
}
|
|
|
|
impl AppError {
|
|
pub fn bad_request(message: impl Into<String>) -> Self {
|
|
Self::BadRequest(message.into())
|
|
}
|
|
|
|
pub fn not_found(message: impl Into<String>) -> Self {
|
|
Self::NotFound(message.into())
|
|
}
|
|
|
|
fn status_code(&self) -> StatusCode {
|
|
match self {
|
|
Self::BadRequest(_) => StatusCode::BAD_REQUEST,
|
|
Self::NotFound(_) => StatusCode::NOT_FOUND,
|
|
Self::Conflict(_) => StatusCode::CONFLICT,
|
|
Self::ServiceUnavailable(_) => StatusCode::SERVICE_UNAVAILABLE,
|
|
Self::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
|
}
|
|
}
|
|
|
|
fn code(&self) -> &'static str {
|
|
match self {
|
|
Self::BadRequest(_) => "bad_request",
|
|
Self::NotFound(_) => "not_found",
|
|
Self::Conflict(_) => "conflict",
|
|
Self::ServiceUnavailable(_) => "service_unavailable",
|
|
Self::Internal(_) => "internal_error",
|
|
}
|
|
}
|
|
}
|
|
|
|
impl IntoResponse for AppError {
|
|
fn into_response(self) -> Response {
|
|
let status = self.status_code();
|
|
let body = Json(ErrorResponse {
|
|
code: self.code(),
|
|
message: self.to_string(),
|
|
});
|
|
|
|
(status, body).into_response()
|
|
}
|
|
}
|