use axum::{ http::StatusCode, response::{IntoResponse, Response}, Json, }; use thiserror::Error; #[derive(Error, Debug)] pub enum AppError { #[error("Unauthorized")] Unauthorized, #[error("Not found")] NotFound, #[error("Bad request: {0}")] BadRequest(String), #[error("Internal error: {0}")] Internal(#[from] anyhow::Error), } impl IntoResponse for AppError { fn into_response(self) -> Response { let (status, message) = match &self { AppError::Unauthorized => (StatusCode::UNAUTHORIZED, self.to_string()), AppError::NotFound => (StatusCode::NOT_FOUND, self.to_string()), AppError::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg.clone()), AppError::Internal(_) => { tracing::error!("{}", self); (StatusCode::INTERNAL_SERVER_ERROR, "Internal server error".into()) } }; (status, Json(serde_json::json!({ "error": message }))).into_response() } } impl From for AppError { fn from(e: sqlx::Error) -> Self { AppError::Internal(anyhow::anyhow!(e)) } } impl From for AppError { fn from(_e: jsonwebtoken::errors::Error) -> Self { AppError::Unauthorized } }