litellm_rs/core/router/
error.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum CooldownReason {
12 RateLimit,
14 AuthError,
16 NotFound,
18 Timeout,
20 ConsecutiveFailures,
22 HighFailureRate,
24 Manual,
26}
27
28#[derive(Debug, Clone, thiserror::Error)]
32pub enum RouterError {
33 #[error("Model not found: {0}")]
35 ModelNotFound(String),
36
37 #[error("No available deployment for model: {0}")]
39 NoAvailableDeployment(String),
40
41 #[error("Deployment not found: {0}")]
43 DeploymentNotFound(String),
44
45 #[error("All deployments in cooldown for model: {0}")]
47 AllDeploymentsInCooldown(String),
48
49 #[error("Rate limit exceeded for model: {0}")]
51 RateLimitExceeded(String),
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
61 fn test_cooldown_reason_rate_limit() {
62 let reason = CooldownReason::RateLimit;
63 assert_eq!(reason, CooldownReason::RateLimit);
64 }
65
66 #[test]
67 fn test_cooldown_reason_auth_error() {
68 let reason = CooldownReason::AuthError;
69 assert_eq!(reason, CooldownReason::AuthError);
70 }
71
72 #[test]
73 fn test_cooldown_reason_not_found() {
74 let reason = CooldownReason::NotFound;
75 assert_eq!(reason, CooldownReason::NotFound);
76 }
77
78 #[test]
79 fn test_cooldown_reason_timeout() {
80 let reason = CooldownReason::Timeout;
81 assert_eq!(reason, CooldownReason::Timeout);
82 }
83
84 #[test]
85 fn test_cooldown_reason_consecutive_failures() {
86 let reason = CooldownReason::ConsecutiveFailures;
87 assert_eq!(reason, CooldownReason::ConsecutiveFailures);
88 }
89
90 #[test]
91 fn test_cooldown_reason_high_failure_rate() {
92 let reason = CooldownReason::HighFailureRate;
93 assert_eq!(reason, CooldownReason::HighFailureRate);
94 }
95
96 #[test]
97 fn test_cooldown_reason_manual() {
98 let reason = CooldownReason::Manual;
99 assert_eq!(reason, CooldownReason::Manual);
100 }
101
102 #[test]
103 fn test_cooldown_reason_clone() {
104 let reason = CooldownReason::RateLimit;
105 let cloned = reason;
106 assert_eq!(reason, cloned);
107 }
108
109 #[test]
110 fn test_cooldown_reason_copy() {
111 let reason = CooldownReason::Timeout;
112 let copied = reason;
113 assert_eq!(reason, copied);
114 }
115
116 #[test]
117 fn test_cooldown_reason_debug() {
118 let reason = CooldownReason::ConsecutiveFailures;
119 let debug_str = format!("{:?}", reason);
120 assert_eq!(debug_str, "ConsecutiveFailures");
121 }
122
123 #[test]
124 fn test_cooldown_reason_equality() {
125 assert_eq!(CooldownReason::RateLimit, CooldownReason::RateLimit);
126 assert_ne!(CooldownReason::RateLimit, CooldownReason::AuthError);
127 }
128
129 #[test]
130 fn test_cooldown_reason_all_variants() {
131 let reasons = [
132 CooldownReason::RateLimit,
133 CooldownReason::AuthError,
134 CooldownReason::NotFound,
135 CooldownReason::Timeout,
136 CooldownReason::ConsecutiveFailures,
137 CooldownReason::HighFailureRate,
138 CooldownReason::Manual,
139 ];
140
141 assert_eq!(reasons.len(), 7);
142 for (i, r1) in reasons.iter().enumerate() {
144 for (j, r2) in reasons.iter().enumerate() {
145 if i != j {
146 assert_ne!(r1, r2);
147 }
148 }
149 }
150 }
151
152 #[test]
155 fn test_router_error_model_not_found() {
156 let error = RouterError::ModelNotFound("gpt-5".to_string());
157 assert_eq!(error.to_string(), "Model not found: gpt-5");
158 }
159
160 #[test]
161 fn test_router_error_no_available_deployment() {
162 let error = RouterError::NoAvailableDeployment("gpt-4".to_string());
163 assert_eq!(
164 error.to_string(),
165 "No available deployment for model: gpt-4"
166 );
167 }
168
169 #[test]
170 fn test_router_error_deployment_not_found() {
171 let error = RouterError::DeploymentNotFound("dep-123".to_string());
172 assert_eq!(error.to_string(), "Deployment not found: dep-123");
173 }
174
175 #[test]
176 fn test_router_error_all_deployments_in_cooldown() {
177 let error = RouterError::AllDeploymentsInCooldown("claude-3".to_string());
178 assert_eq!(
179 error.to_string(),
180 "All deployments in cooldown for model: claude-3"
181 );
182 }
183
184 #[test]
185 fn test_router_error_rate_limit_exceeded() {
186 let error = RouterError::RateLimitExceeded("gpt-4-turbo".to_string());
187 assert_eq!(
188 error.to_string(),
189 "Rate limit exceeded for model: gpt-4-turbo"
190 );
191 }
192
193 #[test]
194 fn test_router_error_clone() {
195 let error = RouterError::ModelNotFound("test".to_string());
196 let cloned = error.clone();
197 assert_eq!(error.to_string(), cloned.to_string());
198 }
199
200 #[test]
201 fn test_router_error_debug() {
202 let error = RouterError::RateLimitExceeded("model".to_string());
203 let debug_str = format!("{:?}", error);
204 assert!(debug_str.contains("RateLimitExceeded"));
205 assert!(debug_str.contains("model"));
206 }
207
208 #[test]
209 fn test_router_error_is_error_trait() {
210 let error = RouterError::ModelNotFound("test".to_string());
211 let _: &dyn std::error::Error = &error;
212 }
213
214 #[test]
215 fn test_router_error_empty_string() {
216 let error = RouterError::ModelNotFound("".to_string());
217 assert_eq!(error.to_string(), "Model not found: ");
218 }
219
220 #[test]
221 fn test_router_error_special_characters() {
222 let error = RouterError::ModelNotFound("model/with:special-chars".to_string());
223 assert_eq!(
224 error.to_string(),
225 "Model not found: model/with:special-chars"
226 );
227 }
228
229 #[test]
230 fn test_router_error_unicode() {
231 let error = RouterError::DeploymentNotFound("部署-123".to_string());
232 assert_eq!(error.to_string(), "Deployment not found: 部署-123");
233 }
234
235 #[test]
236 fn test_router_error_all_variants() {
237 let errors = vec![
238 RouterError::ModelNotFound("a".to_string()),
239 RouterError::NoAvailableDeployment("b".to_string()),
240 RouterError::DeploymentNotFound("c".to_string()),
241 RouterError::AllDeploymentsInCooldown("d".to_string()),
242 RouterError::RateLimitExceeded("e".to_string()),
243 ];
244
245 assert_eq!(errors.len(), 5);
246 for error in errors {
247 assert!(!error.to_string().is_empty());
248 }
249 }
250}