use aimux_core::AiMuxError;
pub struct ErrorStructure {
pub message_path: &'static [&'static str],
pub type_path: &'static [&'static str],
}
pub const DEFAULT_ERROR_STRUCTURE: ErrorStructure = ErrorStructure {
message_path: &["error", "message"],
type_path: &["error", "type"],
};
pub fn parse_provider_error(status: u16, body: &str, structure: &ErrorStructure) -> AiMuxError {
let mut message = format!("HTTP {}", status);
let mut _error_type = String::new();
if let Ok(val) = serde_json::from_str::<serde_json::Value>(body) {
let mut current = &val;
for key in structure.message_path {
if let Some(v) = current.get(key) {
current = v;
} else {
current = &val;
break;
}
}
if let Some(msg) = current.as_str() {
message = msg.to_string();
} else if !body.is_empty() {
message = body.to_string();
}
let mut current = &val;
for key in structure.type_path {
if let Some(v) = current.get(key) {
current = v;
} else {
current = &val;
break;
}
}
if let Some(t) = current.as_str() {
_error_type = t.to_string();
}
} else if !body.is_empty() {
message = body.to_string();
}
match status {
401 => AiMuxError::Auth(message),
429 => AiMuxError::RateLimited {
retry_after_ms: 1000,
},
404 => AiMuxError::ModelNotFound(message),
_ => AiMuxError::Provider(format!("HTTP {}: {}", status, message)),
}
}
pub fn api_call_to_provider_error(error: AiMuxError) -> AiMuxError {
match error {
AiMuxError::ApiCall(message) => AiMuxError::Provider(message),
other => other,
}
}
pub fn provider_403_to_auth(error: AiMuxError) -> AiMuxError {
const PREFIX: &str = "HTTP 403: ";
match error {
AiMuxError::Provider(ref message) if message.starts_with(PREFIX) => {
AiMuxError::Auth(message[PREFIX.len()..].to_string())
}
other => other,
}
}