use axum::{ http::StatusCode, response::{IntoResponse, Response}, Json, }; use serde::Serialize; #[derive(Debug, Serialize)] pub struct XrpcError { pub error: &'static str, pub message: String, } impl XrpcError { pub fn method_not_found(path: &str) -> Self { Self { error: "MethodNotFound", message: format!("Method not found: {}", path), } } pub fn invalid_request(message: impl Into) -> Self { Self { error: "InvalidRequest", message: message.into(), } } pub fn internal_error(message: impl Into) -> Self { Self { error: "InternalServerError", message: message.into(), } } } pub enum ApiError { MethodNotFound(String), InvalidRequest(String), Internal(String), } impl IntoResponse for ApiError { fn into_response(self) -> Response { let (status, error) = match self { ApiError::MethodNotFound(path) => { (StatusCode::NOT_FOUND, XrpcError::method_not_found(&path)) } ApiError::InvalidRequest(msg) => { (StatusCode::BAD_REQUEST, XrpcError::invalid_request(msg)) } ApiError::Internal(msg) => { (StatusCode::INTERNAL_SERVER_ERROR, XrpcError::internal_error(msg)) } }; (status, Json(error)).into_response() } } impl From for ApiError { fn from(e: sqlx::Error) -> Self { ApiError::Internal(e.to_string()) } }