File size: 2,247 Bytes
c71a680 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use axum::Json;
use serde_json::json;
use tracing::error;
#[derive(Debug, thiserror::Error)]
pub enum AppError {
#[error("Not found: {0}")]
NotFound(String),
#[error("Unauthorized: {0}")]
Unauthorized(String),
#[error("Bad request: {0}")]
BadRequest(String),
#[error("Forbidden: {0}")]
Forbidden(String),
#[error("Conflict: {0}")]
Conflict(String),
#[error("{0}")]
Validation(String),
#[error("Internal error")]
Internal,
#[error(transparent)]
Database(#[from] sqlx::Error),
#[error(transparent)]
Jwt(#[from] jsonwebtoken::errors::Error),
#[error(transparent)]
Io(#[from] std::io::Error),
#[error("Argon2 error")]
#[allow(dead_code)]
Argon,
#[error(transparent)]
Reqwest(#[from] reqwest::Error),
}
impl IntoResponse for AppError {
fn into_response(self) -> Response {
error!("AppError: {self:?}");
let (status, message) = match &self {
AppError::NotFound(m) => (StatusCode::NOT_FOUND, m.clone()),
AppError::Unauthorized(m) => (StatusCode::UNAUTHORIZED, m.clone()),
AppError::BadRequest(m) => (StatusCode::BAD_REQUEST, m.clone()),
AppError::Forbidden(m) => (StatusCode::FORBIDDEN, m.clone()),
AppError::Conflict(m) => (StatusCode::CONFLICT, m.clone()),
AppError::Validation(m) => (StatusCode::UNPROCESSABLE_ENTITY, m.clone()),
AppError::Internal => (StatusCode::INTERNAL_SERVER_ERROR, "Internal server error".into()),
AppError::Database(_) => (StatusCode::INTERNAL_SERVER_ERROR, "Internal server error".into()),
AppError::Jwt(_) => (StatusCode::UNAUTHORIZED, "Invalid token".into()),
AppError::Io(_) => (StatusCode::INTERNAL_SERVER_ERROR, "Internal server error".into()),
AppError::Argon => (StatusCode::INTERNAL_SERVER_ERROR, "Internal server error".into()),
AppError::Reqwest(_) => (StatusCode::INTERNAL_SERVER_ERROR, "Internal server error".into()),
};
(status, Json(json!({ "error": message }))).into_response()
}
}
pub type Result<T> = std::result::Result<T, AppError>;
|