Skip to main content

erio_embedding/
error.rs

1//! Embedding-specific error types.
2
3use thiserror::Error;
4
5/// Errors specific to embedding engine operations.
6#[derive(Debug, Error)]
7pub enum EmbeddingError {
8    #[error("Model load failed: {0}")]
9    ModelLoad(String),
10
11    #[error("Tokenization error: {0}")]
12    Tokenization(String),
13
14    #[error("Inference failed: {0}")]
15    Inference(String),
16
17    #[error("Invalid input: {0}")]
18    InvalidInput(String),
19
20    #[error("Dimension mismatch: expected {expected}, got {got}")]
21    DimensionMismatch { expected: usize, got: usize },
22}
23
24impl EmbeddingError {
25    /// Returns `true` if the error is potentially transient and the operation could be retried.
26    ///
27    /// Embedding errors are generally permanent (model/input problems), so this always returns `false`.
28    pub fn is_retryable(&self) -> bool {
29        false
30    }
31}
32
33impl From<EmbeddingError> for erio_core::CoreError {
34    fn from(err: EmbeddingError) -> Self {
35        Self::Embedding {
36            message: err.to_string(),
37        }
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44
45    // === Display Tests ===
46
47    #[test]
48    fn model_load_displays_message() {
49        let err = EmbeddingError::ModelLoad("weights not found".into());
50        assert_eq!(err.to_string(), "Model load failed: weights not found");
51    }
52
53    #[test]
54    fn tokenization_displays_message() {
55        let err = EmbeddingError::Tokenization("unknown token".into());
56        assert_eq!(err.to_string(), "Tokenization error: unknown token");
57    }
58
59    #[test]
60    fn inference_displays_message() {
61        let err = EmbeddingError::Inference("out of memory".into());
62        assert_eq!(err.to_string(), "Inference failed: out of memory");
63    }
64
65    #[test]
66    fn invalid_input_displays_message() {
67        let err = EmbeddingError::InvalidInput("empty text".into());
68        assert_eq!(err.to_string(), "Invalid input: empty text");
69    }
70
71    #[test]
72    fn dimension_mismatch_displays_details() {
73        let err = EmbeddingError::DimensionMismatch {
74            expected: 384,
75            got: 768,
76        };
77        assert_eq!(err.to_string(), "Dimension mismatch: expected 384, got 768");
78    }
79
80    // === Retryable Tests ===
81
82    #[test]
83    fn model_load_is_not_retryable() {
84        let err = EmbeddingError::ModelLoad("missing file".into());
85        assert!(!err.is_retryable());
86    }
87
88    #[test]
89    fn tokenization_is_not_retryable() {
90        let err = EmbeddingError::Tokenization("bad token".into());
91        assert!(!err.is_retryable());
92    }
93
94    #[test]
95    fn inference_is_not_retryable() {
96        let err = EmbeddingError::Inference("oom".into());
97        assert!(!err.is_retryable());
98    }
99
100    #[test]
101    fn invalid_input_is_not_retryable() {
102        let err = EmbeddingError::InvalidInput("empty".into());
103        assert!(!err.is_retryable());
104    }
105
106    #[test]
107    fn dimension_mismatch_is_not_retryable() {
108        let err = EmbeddingError::DimensionMismatch {
109            expected: 384,
110            got: 768,
111        };
112        assert!(!err.is_retryable());
113    }
114
115    // === CoreError Conversion ===
116
117    #[test]
118    fn converts_to_core_error() {
119        let emb_err = EmbeddingError::ModelLoad("test".into());
120        let core_err: erio_core::CoreError = emb_err.into();
121        assert!(matches!(core_err, erio_core::CoreError::Embedding { .. }));
122    }
123
124    #[test]
125    fn conversion_preserves_message() {
126        let emb_err = EmbeddingError::InvalidInput("empty text".into());
127        let core_err: erio_core::CoreError = emb_err.into();
128        match core_err {
129            erio_core::CoreError::Embedding { message } => {
130                assert_eq!(message, "Invalid input: empty text");
131            }
132            _ => panic!("Expected CoreError::Embedding"),
133        }
134    }
135}