1use thiserror::Error;
4
5#[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 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 #[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 #[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 #[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}