use std::io;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum LaurusError {
#[error("I/O error: {0}")]
Io(#[from] io::Error),
#[error("Index error: {0}")]
Index(String),
#[error("Schema error: {0}")]
Schema(String),
#[error("Analysis error: {0}")]
Analysis(String),
#[error("Query error: {0}")]
Query(String),
#[error("Storage error: {0}")]
Storage(String),
#[error("Field error: {0}")]
Field(String),
#[error("Benchmark error: {0}")]
BenchmarkFailed(String),
#[error("Thread join error: {0}")]
ThreadJoinError(String),
#[error("Operation cancelled: {0}")]
OperationCancelled(String),
#[error("Invalid operation: {0}")]
InvalidOperation(String),
#[error("Resource exhausted: {0}")]
ResourceExhausted(String),
#[error("Serialization error: {0}")]
SerializationError(String),
#[error("Not implemented: {0}")]
NotImplemented(String),
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
#[error("Error: {0}")]
Other(String),
#[error("Anyhow error: {0}")]
Anyhow(#[from] anyhow::Error),
}
pub type Result<T> = std::result::Result<T, LaurusError>;
impl LaurusError {
pub fn index<S: Into<String>>(msg: S) -> Self {
LaurusError::Index(msg.into())
}
pub fn schema<S: Into<String>>(msg: S) -> Self {
LaurusError::Schema(msg.into())
}
pub fn analysis<S: Into<String>>(msg: S) -> Self {
LaurusError::Analysis(msg.into())
}
pub fn query<S: Into<String>>(msg: S) -> Self {
LaurusError::Query(msg.into())
}
pub fn parse<S: Into<String>>(msg: S) -> Self {
LaurusError::Query(msg.into()) }
pub fn storage<S: Into<String>>(msg: S) -> Self {
LaurusError::Storage(msg.into())
}
pub fn field<S: Into<String>>(msg: S) -> Self {
LaurusError::Field(msg.into())
}
pub fn other<S: Into<String>>(msg: S) -> Self {
LaurusError::Other(msg.into())
}
pub fn timeout<S: Into<String>>(msg: S) -> Self {
LaurusError::Other(format!("Timeout: {}", msg.into()))
}
pub fn invalid_config<S: Into<String>>(msg: S) -> Self {
LaurusError::Other(format!("Invalid configuration: {}", msg.into()))
}
pub fn invalid_argument<S: Into<String>>(msg: S) -> Self {
LaurusError::Other(format!("Invalid argument: {}", msg.into()))
}
pub fn internal<S: Into<String>>(msg: S) -> Self {
LaurusError::Other(format!("Internal error: {}", msg.into()))
}
pub fn not_found<S: Into<String>>(msg: S) -> Self {
LaurusError::Other(format!("Not found: {}", msg.into()))
}
pub fn cancelled<S: Into<String>>(msg: S) -> Self {
LaurusError::OperationCancelled(msg.into())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_construction() {
let error = LaurusError::index("Test index error");
assert_eq!(error.to_string(), "Index error: Test index error");
let error = LaurusError::schema("Test schema error");
assert_eq!(error.to_string(), "Schema error: Test schema error");
let error = LaurusError::analysis("Test analysis error");
assert_eq!(error.to_string(), "Analysis error: Test analysis error");
}
#[test]
fn test_io_error_conversion() {
let io_error = io::Error::new(io::ErrorKind::NotFound, "File not found");
let iris_error = LaurusError::from(io_error);
match iris_error {
LaurusError::Io(_) => {} _ => panic!("Expected IO error variant"),
}
}
}