use axum::{ http::StatusCode, response::{IntoResponse, Response}, Json, }; use serde::Serialize; #[derive(Debug, thiserror::Error)] pub enum AppError { #[error("bad request: {0}")] BadRequest(String), #[error("provider unavailable: {0}")] ProviderUnavailable(String), #[error("internal error: {0}")] Internal(String), #[error("external service error: {0}")] ExternalService(String), } #[derive(Debug, Serialize)] struct ErrorBody { error: String, } impl IntoResponse for AppError { fn into_response(self) -> Response { let status = match self { AppError::BadRequest(_) => StatusCode::BAD_REQUEST, AppError::ProviderUnavailable(_) => StatusCode::SERVICE_UNAVAILABLE, AppError::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR, AppError::ExternalService(_) => StatusCode::BAD_GATEWAY, }; let body = Json(ErrorBody { error: self.to_string(), }); (status, body).into_response() } } impl From for AppError { fn from(value: sqlx::Error) -> Self { AppError::Internal(value.to_string()) } }