Skip to main content

lattice_embed/
error.rs

1//! Error types for embedding operations.
2
3use thiserror::Error;
4
5/// **Stable**: external consumers may depend on this; breaking changes require a SemVer bump.
6///
7/// Errors that can occur during embedding operations.
8#[derive(Error, Debug)]
9#[non_exhaustive]
10pub enum EmbedError {
11    /// Model not loaded (needs initialization).
12    #[error("model not loaded: {0}")]
13    ModelNotLoaded(String),
14
15    /// Wrong model loaded (concurrent model switch in progress).
16    ///
17    /// This can happen when multiple tasks request different models concurrently.
18    /// The caller should retry with backoff.
19    #[error("wrong model loaded: expected {expected}, got {actual}")]
20    WrongModelLoaded {
21        /// Model that was expected.
22        expected: String,
23        /// Model that was actually loaded.
24        actual: String,
25    },
26
27    /// Model initialization failed.
28    #[error("model initialization failed: {0}")]
29    ModelInitialization(String),
30
31    /// Embedding inference failed.
32    #[error("embedding inference failed: {0}")]
33    InferenceFailed(String),
34
35    /// Blocking task failed (panic or cancellation).
36    ///
37    /// The model cache may be lost; next call will reinitialize.
38    #[error("task execution failed: {0}")]
39    TaskFailed(String),
40
41    /// Invalid input provided.
42    #[error("invalid input: {0}")]
43    InvalidInput(String),
44
45    /// Input text exceeds maximum allowed length.
46    #[error("text too long: {length} chars exceeds maximum {max} chars")]
47    TextTooLong {
48        /// Actual length in characters.
49        length: usize,
50        /// Maximum allowed length.
51        max: usize,
52    },
53
54    /// Dimension mismatch between expected and actual.
55    #[error("dimension mismatch: expected {expected}, got {actual}")]
56    DimensionMismatch {
57        /// Expected dimension.
58        expected: usize,
59        /// Actual dimension.
60        actual: usize,
61    },
62
63    /// Model not supported by this service.
64    #[error("model not supported: {0}")]
65    UnsupportedModel(String),
66
67    /// Internal logic error (count mismatch, unexpected state).
68    #[error("internal error: {0}")]
69    Internal(String),
70}
71
72/// **Stable**: result type alias for embedding operations.
73pub type Result<T> = std::result::Result<T, EmbedError>;
74
75#[cfg(test)]
76mod tests {
77    use super::*;
78
79    #[test]
80    fn test_error_display() {
81        let err = EmbedError::DimensionMismatch {
82            expected: 384,
83            actual: 768,
84        };
85        assert_eq!(err.to_string(), "dimension mismatch: expected 384, got 768");
86    }
87
88    #[test]
89    fn test_error_variants() {
90        let err = EmbedError::ModelNotLoaded("test".into());
91        assert_eq!(err.to_string(), "model not loaded: test");
92
93        let err = EmbedError::WrongModelLoaded {
94            expected: "small".into(),
95            actual: "large".into(),
96        };
97        assert!(err.to_string().contains("expected small"));
98
99        let err = EmbedError::ModelInitialization("failed".into());
100        assert!(err.to_string().contains("initialization"));
101
102        let err = EmbedError::InferenceFailed("oom".into());
103        assert!(err.to_string().contains("inference"));
104
105        let err = EmbedError::TaskFailed("panic".into());
106        assert!(err.to_string().contains("task"));
107
108        let err = EmbedError::InvalidInput("empty".into());
109        assert!(err.to_string().contains("invalid input"));
110
111        let err = EmbedError::UnsupportedModel("gpt4".into());
112        assert!(err.to_string().contains("not supported"));
113
114        let err = EmbedError::Internal("bug".into());
115        assert!(err.to_string().contains("internal"));
116
117        let err = EmbedError::TextTooLong {
118            length: 50000,
119            max: 32768,
120        };
121        assert!(err.to_string().contains("50000"));
122        assert!(err.to_string().contains("32768"));
123    }
124}