1use thiserror::Error;
6
7#[derive(Error, Debug)]
11#[non_exhaustive]
12pub enum EmbedError {
13 #[error("model not loaded: {0}")]
15 ModelNotLoaded(String),
16
17 #[error("wrong model loaded: expected {expected}, got {actual}")]
22 WrongModelLoaded {
23 expected: String,
25 actual: String,
27 },
28
29 #[error("model initialization failed: {0}")]
31 ModelInitialization(String),
32
33 #[error("embedding inference failed: {0}")]
35 InferenceFailed(String),
36
37 #[error("task execution failed: {0}")]
41 TaskFailed(String),
42
43 #[error("invalid input: {0}")]
45 InvalidInput(String),
46
47 #[error("text too long: {length} bytes exceeds maximum {max} bytes")]
49 TextTooLong {
50 length: usize,
52 max: usize,
54 },
55
56 #[error("dimension mismatch: expected {expected}, got {actual}")]
58 DimensionMismatch {
59 expected: usize,
61 actual: usize,
63 },
64
65 #[error("model not supported: {0}")]
67 UnsupportedModel(String),
68
69 #[error("operation not supported: {0}")]
74 Unsupported(String),
75
76 #[error("attestation report size {length} bytes is outside {min}..={max}")]
78 AttestationReportSize {
79 length: usize,
81 min: usize,
83 max: usize,
85 },
86
87 #[error(
89 "resource budget overflow: retained {retained_bytes} bytes plus transient work {transient_work_bytes} bytes"
90 )]
91 ResourceBudgetOverflow {
92 retained_bytes: u64,
94 transient_work_bytes: u64,
96 },
97
98 #[error("internal error: {0}")]
100 Internal(String),
101
102 #[error("tier mismatch in {op}: expected {expected:?}, got {actual:?}")]
105 TierMismatch {
106 op: &'static str,
108 expected: crate::simd::QuantizationTier,
110 actual: crate::simd::QuantizationTier,
112 },
113}
114
115pub type Result<T> = std::result::Result<T, EmbedError>;
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121
122 #[test]
123 fn test_error_display() {
124 let err = EmbedError::DimensionMismatch {
125 expected: 384,
126 actual: 768,
127 };
128 assert_eq!(err.to_string(), "dimension mismatch: expected 384, got 768");
129 }
130
131 #[test]
132 fn test_error_variants() {
133 let err = EmbedError::ModelNotLoaded("test".into());
134 assert_eq!(err.to_string(), "model not loaded: test");
135
136 let err = EmbedError::WrongModelLoaded {
137 expected: "small".into(),
138 actual: "large".into(),
139 };
140 assert!(err.to_string().contains("expected small"));
141
142 let err = EmbedError::ModelInitialization("failed".into());
143 assert!(err.to_string().contains("initialization"));
144
145 let err = EmbedError::InferenceFailed("oom".into());
146 assert!(err.to_string().contains("inference"));
147
148 let err = EmbedError::TaskFailed("panic".into());
149 assert!(err.to_string().contains("task"));
150
151 let err = EmbedError::InvalidInput("empty".into());
152 assert!(err.to_string().contains("invalid input"));
153
154 let err = EmbedError::UnsupportedModel("gpt4".into());
155 assert!(err.to_string().contains("not supported"));
156
157 let err = EmbedError::Unsupported("probe does not implement count_tokens".into());
158 assert_eq!(
159 err.to_string(),
160 "operation not supported: probe does not implement count_tokens"
161 );
162
163 let err = EmbedError::Internal("bug".into());
164 assert!(err.to_string().contains("internal"));
165
166 let err = EmbedError::TextTooLong {
167 length: 50000,
168 max: 32768,
169 };
170 assert!(err.to_string().contains("50000"));
171 assert!(err.to_string().contains("32768"));
172 }
173}