use super::types::GatewayError;
impl GatewayError {
pub fn auth<S: Into<String>>(message: S) -> Self {
Self::Auth(message.into())
}
pub fn authorization<S: Into<String>>(message: S) -> Self {
Self::Forbidden(message.into())
}
pub fn bad_request<S: Into<String>>(message: S) -> Self {
Self::BadRequest(message.into())
}
pub fn not_found<S: Into<String>>(message: S) -> Self {
Self::NotFound(message.into())
}
pub fn conflict<S: Into<String>>(message: S) -> Self {
Self::Conflict(message.into())
}
pub fn internal<S: Into<String>>(message: S) -> Self {
Self::Internal(message.into())
}
pub fn validation<S: Into<String>>(message: S) -> Self {
Self::Validation(message.into())
}
pub fn rate_limit<S: Into<String>>(message: S) -> Self {
Self::RateLimit {
message: message.into(),
retry_after: None,
rpm_limit: None,
tpm_limit: None,
}
}
pub fn timeout<S: Into<String>>(message: S) -> Self {
Self::Timeout(message.into())
}
pub fn service_unavailable<S: Into<String>>(message: S) -> Self {
Self::Unavailable(message.into())
}
pub fn server<S: Into<String>>(message: S) -> Self {
Self::Internal(message.into())
}
pub fn network<S: Into<String>>(message: S) -> Self {
Self::Network(message.into())
}
pub fn external_service<S: Into<String>>(message: S) -> Self {
Self::Internal(message.into())
}
pub fn invalid_request<S: Into<String>>(message: S) -> Self {
Self::BadRequest(message.into())
}
pub fn parsing<S: Into<String>>(message: S) -> Self {
Self::Validation(message.into())
}
pub fn alert<S: Into<String>>(message: S) -> Self {
Self::Internal(message.into())
}
pub fn not_implemented<S: Into<String>>(message: S) -> Self {
Self::NotImplemented(message.into())
}
pub fn unauthorized<S: Into<String>>(message: S) -> Self {
Self::Auth(message.into())
}
pub fn forbidden<S: Into<String>>(message: S) -> Self {
Self::Forbidden(message.into())
}
pub fn external<S: Into<String>>(message: S) -> Self {
Self::Network(message.into())
}
pub fn invalid_request_error<S: Into<String>>(message: S) -> Self {
Self::BadRequest(message.into())
}
pub fn no_providers_available<S: Into<String>>(message: S) -> Self {
Self::Unavailable(message.into())
}
pub fn provider_not_found<S: Into<String>>(message: S) -> Self {
Self::NotFound(message.into())
}
pub fn no_providers_for_model<S: Into<String>>(message: S) -> Self {
Self::BadRequest(message.into())
}
pub fn no_healthy_providers<S: Into<String>>(message: S) -> Self {
Self::Unavailable(message.into())
}
}
impl GatewayError {
pub fn api_error<S: Into<String>>(_status_code: u16, message: S, _provider: S) -> Self {
Self::Internal(message.into())
}
pub fn unavailable<S: Into<String>>(message: S) -> Self {
Self::Unavailable(message.into())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_auth_error_from_string() {
let error = GatewayError::auth("Invalid API key");
assert!(matches!(error, GatewayError::Auth(msg) if msg == "Invalid API key"));
}
#[test]
fn test_auth_error_from_str() {
let error = GatewayError::auth("Token expired");
assert!(matches!(error, GatewayError::Auth(_)));
}
#[test]
fn test_authorization_error() {
let error = GatewayError::authorization("Insufficient permissions");
assert!(matches!(error, GatewayError::Forbidden(msg) if msg == "Insufficient permissions"));
}
#[test]
fn test_bad_request_error() {
let error = GatewayError::bad_request("Missing required field");
assert!(matches!(error, GatewayError::BadRequest(msg) if msg == "Missing required field"));
}
#[test]
fn test_not_found_error() {
let error = GatewayError::not_found("Resource not found");
assert!(matches!(error, GatewayError::NotFound(msg) if msg == "Resource not found"));
}
#[test]
fn test_conflict_error() {
let error = GatewayError::conflict("Resource already exists");
assert!(matches!(error, GatewayError::Conflict(msg) if msg == "Resource already exists"));
}
#[test]
fn test_validation_error() {
let error = GatewayError::validation("Invalid input format");
assert!(matches!(error, GatewayError::Validation(msg) if msg == "Invalid input format"));
}
#[test]
fn test_invalid_request_error() {
let error = GatewayError::invalid_request("Malformed JSON");
assert!(matches!(error, GatewayError::BadRequest(msg) if msg == "Malformed JSON"));
}
#[test]
fn test_invalid_request_error_method() {
let error = GatewayError::invalid_request_error("Invalid format");
assert!(matches!(error, GatewayError::BadRequest(msg) if msg == "Invalid format"));
}
#[test]
fn test_internal_error() {
let error = GatewayError::internal("Internal server error");
assert!(matches!(error, GatewayError::Internal(msg) if msg == "Internal server error"));
}
#[test]
fn test_server_error_maps_to_internal() {
let error = GatewayError::server("Server failure");
assert!(matches!(error, GatewayError::Internal(msg) if msg == "Server failure"));
}
#[test]
fn test_external_service_maps_to_internal() {
let error = GatewayError::external_service("External API failed");
assert!(matches!(error, GatewayError::Internal(msg) if msg == "External API failed"));
}
#[test]
fn test_api_error_maps_to_internal() {
let error = GatewayError::api_error(500, "Server error", "openai");
assert!(matches!(error, GatewayError::Internal(msg) if msg == "Server error"));
}
#[test]
fn test_rate_limit_error() {
let error = GatewayError::rate_limit("Rate limit exceeded");
assert!(
matches!(error, GatewayError::RateLimit { ref message, .. } if message == "Rate limit exceeded")
);
}
#[test]
fn test_timeout_error() {
let error = GatewayError::timeout("Request timed out after 30s");
assert!(
matches!(error, GatewayError::Timeout(msg) if msg == "Request timed out after 30s")
);
}
#[test]
fn test_service_unavailable_error() {
let error = GatewayError::service_unavailable("Service under maintenance");
assert!(
matches!(error, GatewayError::Unavailable(msg) if msg == "Service under maintenance")
);
}
#[test]
fn test_unavailable_error() {
let error = GatewayError::unavailable("Provider unavailable");
assert!(matches!(error, GatewayError::Unavailable(msg) if msg == "Provider unavailable"));
}
#[test]
fn test_no_providers_available() {
let error = GatewayError::no_providers_available("No providers configured");
assert!(
matches!(error, GatewayError::Unavailable(msg) if msg == "No providers configured")
);
}
#[test]
fn test_provider_not_found() {
let error = GatewayError::provider_not_found("openai");
assert!(matches!(error, GatewayError::NotFound(msg) if msg == "openai"));
}
#[test]
fn test_no_providers_for_model() {
let error = GatewayError::no_providers_for_model("gpt-5");
assert!(matches!(error, GatewayError::BadRequest(msg) if msg == "gpt-5"));
}
#[test]
fn test_no_healthy_providers() {
let error = GatewayError::no_healthy_providers("All providers are down");
assert!(matches!(error, GatewayError::Unavailable(msg) if msg == "All providers are down"));
}
#[test]
fn test_network_error() {
let error = GatewayError::network("Connection refused");
assert!(matches!(error, GatewayError::Network(msg) if msg == "Connection refused"));
}
#[test]
fn test_parsing_error() {
let error = GatewayError::parsing("Invalid JSON syntax");
assert!(matches!(error, GatewayError::Validation(msg) if msg == "Invalid JSON syntax"));
}
#[test]
fn test_alert_error() {
let error = GatewayError::alert("Critical threshold exceeded");
assert!(
matches!(error, GatewayError::Internal(msg) if msg == "Critical threshold exceeded")
);
}
#[test]
fn test_not_implemented_error() {
let error = GatewayError::not_implemented("Feature not yet available");
assert!(
matches!(error, GatewayError::NotImplemented(msg) if msg == "Feature not yet available")
);
}
#[test]
fn test_unauthorized_error() {
let error = GatewayError::unauthorized("Invalid credentials");
assert!(matches!(error, GatewayError::Auth(msg) if msg == "Invalid credentials"));
}
#[test]
fn test_forbidden_error() {
let error = GatewayError::forbidden("Access denied");
assert!(matches!(error, GatewayError::Forbidden(msg) if msg == "Access denied"));
}
#[test]
fn test_external_error() {
let error = GatewayError::external("Third-party service error");
assert!(matches!(error, GatewayError::Network(msg) if msg == "Third-party service error"));
}
#[test]
fn test_error_from_owned_string() {
let message = String::from("Dynamic error message");
let error = GatewayError::auth(message);
assert!(matches!(error, GatewayError::Auth(msg) if msg == "Dynamic error message"));
}
#[test]
fn test_error_from_string_slice() {
let error = GatewayError::auth("Static error message");
assert!(matches!(error, GatewayError::Auth(msg) if msg == "Static error message"));
}
#[test]
fn test_error_with_format_string() {
let model = "gpt-4";
let error = GatewayError::no_providers_for_model(format!("No provider supports {}", model));
assert!(matches!(error, GatewayError::BadRequest(msg) if msg.contains("gpt-4")));
}
#[test]
fn test_error_with_empty_string() {
let error = GatewayError::auth("");
assert!(matches!(error, GatewayError::Auth(msg) if msg.is_empty()));
}
#[test]
fn test_error_with_unicode() {
let error = GatewayError::auth("认证失败 - Authentication failed");
assert!(matches!(error, GatewayError::Auth(msg) if msg.contains("认证失败")));
}
#[test]
fn test_error_with_special_characters() {
let error = GatewayError::parsing("JSON error at line 5: unexpected '}'");
assert!(matches!(error, GatewayError::Validation(msg) if msg.contains("unexpected '}'")));
}
#[test]
fn test_error_with_newlines() {
let error = GatewayError::internal("Error details:\n- Issue 1\n- Issue 2");
assert!(matches!(error, GatewayError::Internal(msg) if msg.contains('\n')));
}
#[test]
fn test_service_unavailable_matches_unavailable() {
let error1 = GatewayError::service_unavailable("test");
let error2 = GatewayError::unavailable("test");
assert!(matches!(error1, GatewayError::Unavailable(_)));
assert!(matches!(error2, GatewayError::Unavailable(_)));
}
#[test]
fn test_server_matches_internal() {
let error1 = GatewayError::server("test");
let error2 = GatewayError::internal("test");
assert!(matches!(error1, GatewayError::Internal(_)));
assert!(matches!(error2, GatewayError::Internal(_)));
}
#[test]
fn test_invalid_request_matches_bad_request() {
let error1 = GatewayError::invalid_request("test");
let error2 = GatewayError::bad_request("test");
assert!(matches!(error1, GatewayError::BadRequest(_)));
assert!(matches!(error2, GatewayError::BadRequest(_)));
}
#[test]
fn test_all_helper_methods_exist() {
let _ = GatewayError::auth("test");
let _ = GatewayError::authorization("test");
let _ = GatewayError::bad_request("test");
let _ = GatewayError::not_found("test");
let _ = GatewayError::conflict("test");
let _ = GatewayError::internal("test");
let _ = GatewayError::validation("test");
let _ = GatewayError::rate_limit("test");
let _ = GatewayError::timeout("test");
let _ = GatewayError::service_unavailable("test");
let _ = GatewayError::server("test");
let _ = GatewayError::network("test");
let _ = GatewayError::external_service("test");
let _ = GatewayError::invalid_request("test");
let _ = GatewayError::parsing("test");
let _ = GatewayError::alert("test");
let _ = GatewayError::not_implemented("test");
let _ = GatewayError::unauthorized("test");
let _ = GatewayError::forbidden("test");
let _ = GatewayError::external("test");
let _ = GatewayError::invalid_request_error("test");
let _ = GatewayError::no_providers_available("test");
let _ = GatewayError::provider_not_found("test");
let _ = GatewayError::no_providers_for_model("test");
let _ = GatewayError::no_healthy_providers("test");
let _ = GatewayError::api_error(500, "test", "provider");
let _ = GatewayError::unavailable("test");
}
}