Skip to main content

postrust_proxy/
error.rs

1//! Error types for the proxy module.
2
3use thiserror::Error;
4
5/// Result type for proxy operations.
6pub type ProxyResult<T> = Result<T, ProxyError>;
7
8/// Errors that can occur in the proxy module.
9#[derive(Error, Debug)]
10pub enum ProxyError {
11    /// Configuration error
12    #[error("Configuration error: {0}")]
13    Config(String),
14
15    /// Database error
16    #[error("Database error: {0}")]
17    Database(#[from] sqlx::Error),
18
19    /// IO error
20    #[error("IO error: {0}")]
21    Io(#[from] std::io::Error),
22
23    /// TLS error
24    #[error("TLS error: {0}")]
25    Tls(String),
26
27    /// ACME error
28    #[error("ACME error: {0}")]
29    Acme(String),
30
31    /// HTTP error
32    #[error("HTTP error: {0}")]
33    Http(String),
34
35    /// Upstream error
36    #[error("Upstream error: {0}")]
37    Upstream(String),
38
39    /// Health check error
40    #[error("Health check error: {0}")]
41    HealthCheck(String),
42
43    /// Rate limit exceeded
44    #[error("Rate limit exceeded")]
45    RateLimitExceeded,
46
47    /// Route not found
48    #[error("Route not found: {0}")]
49    RouteNotFound(String),
50
51    /// Backend not found
52    #[error("Backend not found: {0}")]
53    BackendNotFound(String),
54
55    /// No healthy backends
56    #[error("No healthy backends available for upstream: {0}")]
57    NoHealthyBackends(String),
58
59    /// Invalid URL
60    #[error("Invalid URL: {0}")]
61    InvalidUrl(#[from] url::ParseError),
62
63    /// TOML parsing error
64    #[error("TOML parsing error: {0}")]
65    Toml(#[from] toml::de::Error),
66
67    /// File watcher error
68    #[error("File watcher error: {0}")]
69    Notify(#[from] notify::Error),
70
71    /// Internal error
72    #[error("Internal error: {0}")]
73    Internal(String),
74
75    // SaaS Domain Management Errors
76    /// Domain verification error
77    #[error("Domain verification error: {0}")]
78    Verification(String),
79
80    /// Authentication error
81    #[error("Authentication error: {0}")]
82    Auth(String),
83
84    /// Validation error
85    #[error("Validation error: {0}")]
86    Validation(String),
87
88    /// Quota exceeded
89    #[error("Quota exceeded: {0}")]
90    QuotaExceeded(String),
91
92    /// Resource conflict
93    #[error("Conflict: {0}")]
94    Conflict(String),
95
96    /// Tenant suspended
97    #[error("Tenant suspended")]
98    TenantSuspended,
99
100    /// Not found
101    #[error("Not found: {0}")]
102    NotFound(String),
103
104    /// Forbidden
105    #[error("Forbidden: {0}")]
106    Forbidden(String),
107}
108
109impl ProxyError {
110    /// Get the HTTP status code for this error.
111    pub fn status_code(&self) -> http::StatusCode {
112        match self {
113            ProxyError::Config(_) => http::StatusCode::INTERNAL_SERVER_ERROR,
114            ProxyError::Database(_) => http::StatusCode::INTERNAL_SERVER_ERROR,
115            ProxyError::Io(_) => http::StatusCode::INTERNAL_SERVER_ERROR,
116            ProxyError::Tls(_) => http::StatusCode::INTERNAL_SERVER_ERROR,
117            ProxyError::Acme(_) => http::StatusCode::INTERNAL_SERVER_ERROR,
118            ProxyError::Http(_) => http::StatusCode::BAD_GATEWAY,
119            ProxyError::Upstream(_) => http::StatusCode::BAD_GATEWAY,
120            ProxyError::HealthCheck(_) => http::StatusCode::SERVICE_UNAVAILABLE,
121            ProxyError::RateLimitExceeded => http::StatusCode::TOO_MANY_REQUESTS,
122            ProxyError::RouteNotFound(_) => http::StatusCode::NOT_FOUND,
123            ProxyError::BackendNotFound(_) => http::StatusCode::NOT_FOUND,
124            ProxyError::NoHealthyBackends(_) => http::StatusCode::SERVICE_UNAVAILABLE,
125            ProxyError::InvalidUrl(_) => http::StatusCode::BAD_REQUEST,
126            ProxyError::Toml(_) => http::StatusCode::INTERNAL_SERVER_ERROR,
127            ProxyError::Notify(_) => http::StatusCode::INTERNAL_SERVER_ERROR,
128            ProxyError::Internal(_) => http::StatusCode::INTERNAL_SERVER_ERROR,
129            ProxyError::Verification(_) => http::StatusCode::BAD_REQUEST,
130            ProxyError::Auth(_) => http::StatusCode::UNAUTHORIZED,
131            ProxyError::Validation(_) => http::StatusCode::BAD_REQUEST,
132            ProxyError::QuotaExceeded(_) => http::StatusCode::PAYMENT_REQUIRED,
133            ProxyError::Conflict(_) => http::StatusCode::CONFLICT,
134            ProxyError::TenantSuspended => http::StatusCode::FORBIDDEN,
135            ProxyError::NotFound(_) => http::StatusCode::NOT_FOUND,
136            ProxyError::Forbidden(_) => http::StatusCode::FORBIDDEN,
137        }
138    }
139}