use thiserror::Error;
#[derive(Debug, Error)]
pub enum OxiRagError {
#[error("Embedding error: {0}")]
Embedding(#[from] EmbeddingError),
#[error("Vector store error: {0}")]
VectorStore(#[from] VectorStoreError),
#[error("Speculator error: {0}")]
Speculator(#[from] SpeculatorError),
#[error("Judge error: {0}")]
Judge(#[from] JudgeError),
#[cfg(feature = "graphrag")]
#[error("Graph error: {0}")]
Graph(#[from] GraphError),
#[cfg(feature = "distillation")]
#[error("Distillation error: {0}")]
Distillation(#[from] DistillationError),
#[cfg(feature = "prefix-cache")]
#[error("Prefix cache error: {0}")]
PrefixCache(#[from] PrefixCacheError),
#[cfg(feature = "hidden-states")]
#[error("Hidden state error: {0}")]
HiddenState(#[from] HiddenStateError),
#[error("Memory error: {0}")]
Memory(#[from] crate::memory::MemoryError),
#[error("Pipeline error: {0}")]
Pipeline(#[from] PipelineError),
#[error("Circuit breaker error: {0}")]
CircuitBreaker(#[from] CircuitBreakerError),
#[error("Configuration error: {0}")]
Config(String),
#[cfg(feature = "native")]
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[cfg(not(feature = "native"))]
#[error("IO error: {0}")]
Io(String),
#[error("Serialization error: {0}")]
Serialization(#[from] serde_json::Error),
}
#[derive(Debug, Error)]
pub enum EmbeddingError {
#[error("Failed to load embedding model: {0}")]
ModelLoad(String),
#[error("Tokenization failed: {0}")]
Tokenization(String),
#[error("Inference failed: {0}")]
Inference(String),
#[error("Dimension mismatch: expected {expected}, got {actual}")]
DimensionMismatch {
expected: usize,
actual: usize,
},
#[error("Empty input provided")]
EmptyInput,
#[error("Backend error: {0}")]
Backend(String),
}
#[derive(Debug, Error)]
pub enum VectorStoreError {
#[error("Document not found: {0}")]
NotFound(String),
#[error("Duplicate document ID: {0}")]
DuplicateId(String),
#[error("Storage capacity exceeded: max {max}, current {current}")]
CapacityExceeded {
max: usize,
current: usize,
},
#[error("Index error: {0}")]
Index(String),
#[error("Vector dimension mismatch: expected {expected}, got {actual}")]
DimensionMismatch {
expected: usize,
actual: usize,
},
}
#[derive(Debug, Error)]
pub enum SpeculatorError {
#[error("Failed to load speculator model: {0}")]
ModelLoad(String),
#[error("Generation failed: {0}")]
Generation(String),
#[error("Verification failed: {0}")]
Verification(String),
#[error("Invalid draft: {0}")]
InvalidDraft(String),
#[error("Context too long: {length} tokens exceeds max {max}")]
ContextTooLong {
length: usize,
max: usize,
},
#[error("Backend error: {0}")]
Backend(String),
}
#[derive(Debug, Error)]
pub enum JudgeError {
#[error("Claim extraction failed: {0}")]
ExtractionFailed(String),
#[error("SMT encoding failed: {0}")]
EncodingFailed(String),
#[error("Solver error: {0}")]
SolverError(String),
#[error("Verification timeout after {0}ms")]
Timeout(u64),
#[error("Inconsistent claims detected: {0}")]
InconsistentClaims(String),
#[error("Unsupported claim type: {0}")]
UnsupportedClaim(String),
}
#[derive(Debug, Error)]
pub enum PipelineError {
#[error("Layer not configured: {0}")]
LayerNotConfigured(String),
#[error("Pipeline build error: {0}")]
BuildError(String),
#[error("Pipeline execution error: {0}")]
ExecutionError(String),
#[error("Invalid threshold: {0}")]
InvalidThreshold(String),
}
#[cfg(feature = "distillation")]
#[derive(Debug, Error)]
pub enum DistillationError {
#[error("Query tracking failed: {0}")]
TrackingFailed(String),
#[error("Collection failed: {0}")]
CollectionFailed(String),
#[error("Invalid configuration: {0}")]
InvalidConfig(String),
#[error("Pattern not found: {0}")]
PatternNotFound(String),
#[error("Storage error: {0}")]
StorageError(String),
}
#[cfg(feature = "prefix-cache")]
#[derive(Debug, Error)]
pub enum PrefixCacheError {
#[error("Cache entry not found: {0}")]
NotFound(String),
#[error("Cache capacity exceeded: {0}")]
CapacityExceeded(String),
#[error("Invalid configuration: {0}")]
InvalidConfig(String),
#[error("Fingerprint generation failed: {0}")]
FingerprintError(String),
#[error("Entry expired: {0}")]
Expired(String),
#[error("Lock acquisition failed: {0}")]
LockError(String),
}
#[cfg(feature = "graphrag")]
#[derive(Debug, Error)]
pub enum GraphError {
#[error("Entity not found: {0}")]
EntityNotFound(String),
#[error("Relationship not found: {0}")]
RelationshipNotFound(String),
#[error("Entity extraction failed: {0}")]
ExtractionFailed(String),
#[error("Traversal error: {0}")]
TraversalError(String),
#[error("Configuration error: {0}")]
ConfigurationError(String),
#[error("Storage error: {0}")]
StorageError(String),
#[error("Invalid query: {0}")]
InvalidQuery(String),
}
#[derive(Debug, Error)]
pub enum CircuitBreakerError {
#[error("Circuit breaker is open: {0}")]
Open(String),
#[error("Circuit breaker is half-open, max requests reached: {0}")]
HalfOpenMaxRequests(String),
#[error("Invalid configuration: {0}")]
InvalidConfig(String),
}
#[cfg(feature = "hidden-states")]
#[derive(Debug, Clone, Error)]
pub enum HiddenStateError {
#[error("Shape mismatch: expected {expected:?}, got {actual:?}")]
ShapeMismatch {
expected: Vec<usize>,
actual: Vec<usize>,
},
#[error("Invalid dimension: {0}")]
InvalidDimension(String),
#[error("Cache error: {0}")]
CacheError(String),
#[error("Provider error: {0}")]
ProviderError(String),
}
pub type Result<T> = std::result::Result<T, OxiRagError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let err = OxiRagError::Config("invalid setting".into());
assert_eq!(err.to_string(), "Configuration error: invalid setting");
}
#[test]
fn test_embedding_error_conversion() {
let emb_err = EmbeddingError::EmptyInput;
let err: OxiRagError = emb_err.into();
assert!(matches!(err, OxiRagError::Embedding(_)));
}
#[test]
fn test_vector_store_error_conversion() {
let vs_err = VectorStoreError::NotFound("doc123".into());
let err: OxiRagError = vs_err.into();
assert!(matches!(err, OxiRagError::VectorStore(_)));
}
}