1use axum::{
4 http::StatusCode,
5 response::{IntoResponse, Response},
6 Json,
7};
8use serde::Serialize;
9use thiserror::Error;
10
11#[derive(Debug, Error)]
13pub enum ProxyError {
14 #[error("Failed to create HTTP client: {0}")]
16 ClientCreation(String),
17
18 #[error("Failed to read request body: {0}")]
20 RequestBody(String),
21
22 #[error("Backend request failed: {0}")]
24 BackendRequest(String),
25
26 #[error("Failed to read response body: {0}")]
28 ResponseBody(String),
29
30 #[error("Route not found for: {0}")]
32 RouteNotFound(String),
33
34 #[error("Invalid configuration: {0}")]
36 InvalidConfig(String),
37}
38
39impl IntoResponse for ProxyError {
40 fn into_response(self) -> Response {
41 let (status, error_message) = match &self {
42 ProxyError::RouteNotFound(_) => (StatusCode::NOT_FOUND, self.to_string()),
43 ProxyError::InvalidConfig(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()),
44 ProxyError::BackendRequest(_) => (StatusCode::BAD_GATEWAY, self.to_string()),
45 _ => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()),
46 };
47
48 #[derive(Serialize)]
49 struct ErrorResponse {
50 error: String,
51 message: String,
52 }
53
54 let body = Json(ErrorResponse {
55 error: "PROXY_ERROR".to_string(),
56 message: error_message,
57 });
58
59 (status, body).into_response()
60 }
61}
62
63pub type ProxyResult<T> = Result<T, ProxyError>;