turul_http_mcp_server/middleware/
error.rs1use std::fmt;
4
5pub mod error_codes {
10 pub const UNAUTHENTICATED: i64 = -32001;
12 pub const UNAUTHORIZED: i64 = -32002;
14 pub const RATE_LIMIT_EXCEEDED: i64 = -32003;
16 pub const INVALID_REQUEST: i64 = -32600;
18 pub const INTERNAL_ERROR: i64 = -32603;
20}
21
22#[derive(Debug, Clone, PartialEq)]
78pub enum MiddlewareError {
79 Unauthenticated(String),
81
82 Unauthorized(String),
84
85 RateLimitExceeded {
87 message: String,
89 retry_after: Option<u64>,
91 },
92
93 InvalidRequest(String),
95
96 Internal(String),
98
99 Custom {
101 code: String,
103 message: String,
105 },
106}
107
108impl fmt::Display for MiddlewareError {
109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110 match self {
111 Self::Unauthenticated(msg) => write!(f, "Authentication required: {}", msg),
112 Self::Unauthorized(msg) => write!(f, "Unauthorized: {}", msg),
113 Self::RateLimitExceeded { message, retry_after } => {
114 if let Some(seconds) = retry_after {
115 write!(f, "{} (retry after {} seconds)", message, seconds)
116 } else {
117 write!(f, "{}", message)
118 }
119 }
120 Self::InvalidRequest(msg) => write!(f, "Invalid request: {}", msg),
121 Self::Internal(msg) => write!(f, "Internal middleware error: {}", msg),
122 Self::Custom { code, message } => write!(f, "{}: {}", code, message),
123 }
124 }
125}
126
127impl std::error::Error for MiddlewareError {}
128
129impl MiddlewareError {
130 pub fn unauthenticated(msg: impl Into<String>) -> Self {
132 Self::Unauthenticated(msg.into())
133 }
134
135 pub fn unauthorized(msg: impl Into<String>) -> Self {
137 Self::Unauthorized(msg.into())
138 }
139
140 pub fn rate_limit(msg: impl Into<String>, retry_after: Option<u64>) -> Self {
142 Self::RateLimitExceeded {
143 message: msg.into(),
144 retry_after,
145 }
146 }
147
148 pub fn invalid_request(msg: impl Into<String>) -> Self {
150 Self::InvalidRequest(msg.into())
151 }
152
153 pub fn internal(msg: impl Into<String>) -> Self {
155 Self::Internal(msg.into())
156 }
157
158 pub fn custom(code: impl Into<String>, message: impl Into<String>) -> Self {
160 Self::Custom {
161 code: code.into(),
162 message: message.into(),
163 }
164 }
165}
166
167#[cfg(test)]
168mod tests {
169 use super::*;
170
171 #[test]
172 fn test_error_display() {
173 let err = MiddlewareError::unauthenticated("Missing token");
174 assert_eq!(err.to_string(), "Authentication required: Missing token");
175
176 let err = MiddlewareError::unauthorized("Insufficient permissions");
177 assert_eq!(err.to_string(), "Unauthorized: Insufficient permissions");
178
179 let err = MiddlewareError::rate_limit("Too many requests", Some(60));
180 assert_eq!(err.to_string(), "Too many requests (retry after 60 seconds)");
181
182 let err = MiddlewareError::rate_limit("Too many requests", None);
183 assert_eq!(err.to_string(), "Too many requests");
184
185 let err = MiddlewareError::invalid_request("Malformed params");
186 assert_eq!(err.to_string(), "Invalid request: Malformed params");
187
188 let err = MiddlewareError::internal("Database connection failed");
189 assert_eq!(err.to_string(), "Internal middleware error: Database connection failed");
190
191 let err = MiddlewareError::custom("CUSTOM_ERROR", "Something went wrong");
192 assert_eq!(err.to_string(), "CUSTOM_ERROR: Something went wrong");
193 }
194
195 #[test]
196 fn test_error_equality() {
197 let err1 = MiddlewareError::unauthenticated("test");
198 let err2 = MiddlewareError::unauthenticated("test");
199 assert_eq!(err1, err2);
200
201 let err3 = MiddlewareError::rate_limit("test", Some(60));
202 let err4 = MiddlewareError::rate_limit("test", Some(60));
203 assert_eq!(err3, err4);
204 }
205}