use thiserror::Error;
pub type Result<T> = std::result::Result<T, VectorDBError>;
#[derive(Error, Debug)]
pub enum VectorDBError {
#[error("Parameter error: {message}")]
ParamError { code: i32, message: String },
#[error("Connection error: {message}")]
ConnectError { code: i32, message: String },
#[error("Server internal error: {message}")]
ServerInternalError { code: i32, message: String },
#[error("Collection describe error: {message}")]
DescribeCollectionError { code: i32, message: String },
#[error("HTTP request error: {0}")]
HttpError(#[from] reqwest::Error),
#[error("JSON serialization error: {0}")]
JsonError(#[from] serde_json::Error),
#[error("URL parse error: {0}")]
UrlError(#[from] url::ParseError),
#[error("Unexpected error: {message}")]
UnexpectedError { message: String },
}
impl VectorDBError {
pub fn param_error(code: i32, message: impl Into<String>) -> Self {
Self::ParamError {
code,
message: message.into(),
}
}
pub fn connect_error(code: i32, message: impl Into<String>) -> Self {
Self::ConnectError {
code,
message: message.into(),
}
}
pub fn server_error(code: i32, message: impl Into<String>) -> Self {
Self::ServerInternalError {
code,
message: message.into(),
}
}
pub fn unexpected_error(message: impl Into<String>) -> Self {
Self::UnexpectedError {
message: message.into(),
}
}
pub fn diagnose_http_error(&self) -> Option<String> {
match self {
VectorDBError::HttpError(e) => {
let mut diagnosis = String::new();
if e.is_connect() {
diagnosis.push_str("Connection failed. Possible causes:\n");
diagnosis.push_str(" 1. VectorDB service is not running\n");
diagnosis.push_str(" 2. Incorrect server address or port\n");
diagnosis.push_str(" 3. Network connectivity issues\n");
diagnosis.push_str(" 4. Firewall blocking the connection\n");
} else if e.is_timeout() {
diagnosis.push_str("Request timed out. Possible causes:\n");
diagnosis.push_str(" 1. Server is overloaded or slow\n");
diagnosis.push_str(" 2. Network latency is high\n");
diagnosis.push_str(" 3. Increase timeout duration\n");
} else if e.is_request() {
diagnosis.push_str("Request error. Possible causes:\n");
diagnosis.push_str(" 1. Invalid URL format\n");
diagnosis.push_str(" 2. Malformed request data\n");
} else if e.is_decode() {
diagnosis.push_str("Response decode error. Possible causes:\n");
diagnosis.push_str(" 1. Server returned invalid JSON\n");
diagnosis.push_str(" 2. API version mismatch\n");
}
Some(diagnosis)
}
VectorDBError::ConnectError { code, .. } => {
match *code {
401 => Some("Authentication failed. Check your API key and username.".to_string()),
403 => Some("Access forbidden. Check your permissions.".to_string()),
404 => Some("Endpoint not found. Check the server URL and API version.".to_string()),
500..=599 => Some("Server error. The VectorDB service may be experiencing issues.".to_string()),
_ => None,
}
}
_ => None,
}
}
}