Skip to main content

oximedia_recommend/
error.rs

1//! Error types for recommendation engine.
2
3use thiserror::Error;
4
5/// Result type for recommendation operations
6pub type RecommendResult<T> = Result<T, RecommendError>;
7
8/// Errors that can occur during recommendation operations
9#[derive(Debug, Error)]
10pub enum RecommendError {
11    /// User not found
12    #[error("User not found: {0}")]
13    UserNotFound(uuid::Uuid),
14
15    /// Content not found
16    #[error("Content not found: {0}")]
17    ContentNotFound(uuid::Uuid),
18
19    /// Insufficient data for recommendation
20    #[error("Insufficient data: {0}")]
21    InsufficientData(String),
22
23    /// Invalid rating value
24    #[error("Invalid rating: {0}")]
25    InvalidRating(f32),
26
27    /// Invalid similarity score
28    #[error("Invalid similarity score: {0}")]
29    InvalidSimilarity(f32),
30
31    /// Matrix computation error
32    #[error("Matrix computation error: {0}")]
33    MatrixError(String),
34
35    /// Profile error
36    #[error("Profile error: {0}")]
37    ProfileError(String),
38
39    /// History tracking error
40    #[error("History tracking error: {0}")]
41    HistoryError(String),
42
43    /// Trending detection error
44    #[error("Trending detection error: {0}")]
45    TrendingError(String),
46
47    /// Personalization error
48    #[error("Personalization error: {0}")]
49    PersonalizationError(String),
50
51    /// Diversity enforcement error
52    #[error("Diversity enforcement error: {0}")]
53    DiversityError(String),
54
55    /// Ranking error
56    #[error("Ranking error: {0}")]
57    RankingError(String),
58
59    /// Explanation generation error
60    #[error("Explanation generation error: {0}")]
61    ExplanationError(String),
62
63    /// IO error
64    #[error("IO error: {0}")]
65    IoError(#[from] std::io::Error),
66
67    /// Serialization error
68    #[error("Serialization error: {0}")]
69    SerializationError(#[from] serde_json::Error),
70
71    /// Request was rate-limited
72    #[error("Rate limited: {0}")]
73    RateLimited(String),
74
75    /// ML pipeline error (only available when the `onnx` feature is enabled).
76    #[cfg(feature = "onnx")]
77    #[error("ML error: {0}")]
78    Ml(#[from] oximedia_ml::MlError),
79
80    /// Generic error
81    #[error("{0}")]
82    Other(String),
83}
84
85impl RecommendError {
86    /// Create an insufficient data error
87    #[must_use]
88    pub fn insufficient_data(msg: impl Into<String>) -> Self {
89        Self::InsufficientData(msg.into())
90    }
91
92    /// Create a matrix error
93    #[must_use]
94    pub fn matrix_error(msg: impl Into<String>) -> Self {
95        Self::MatrixError(msg.into())
96    }
97
98    /// Create a profile error
99    #[must_use]
100    pub fn profile_error(msg: impl Into<String>) -> Self {
101        Self::ProfileError(msg.into())
102    }
103
104    /// Create a history error
105    #[must_use]
106    pub fn history_error(msg: impl Into<String>) -> Self {
107        Self::HistoryError(msg.into())
108    }
109
110    /// Create a trending error
111    #[must_use]
112    pub fn trending_error(msg: impl Into<String>) -> Self {
113        Self::TrendingError(msg.into())
114    }
115
116    /// Create a personalization error
117    #[must_use]
118    pub fn personalization_error(msg: impl Into<String>) -> Self {
119        Self::PersonalizationError(msg.into())
120    }
121
122    /// Create a diversity error
123    #[must_use]
124    pub fn diversity_error(msg: impl Into<String>) -> Self {
125        Self::DiversityError(msg.into())
126    }
127
128    /// Create a ranking error
129    #[must_use]
130    pub fn ranking_error(msg: impl Into<String>) -> Self {
131        Self::RankingError(msg.into())
132    }
133
134    /// Create an explanation error
135    #[must_use]
136    pub fn explanation_error(msg: impl Into<String>) -> Self {
137        Self::ExplanationError(msg.into())
138    }
139}
140
141#[cfg(test)]
142mod tests {
143    use super::*;
144    use uuid::Uuid;
145
146    #[test]
147    fn test_user_not_found_error() {
148        let id = Uuid::new_v4();
149        let error = RecommendError::UserNotFound(id);
150        assert!(error.to_string().contains("User not found"));
151    }
152
153    #[test]
154    fn test_insufficient_data_error() {
155        let error = RecommendError::insufficient_data("Not enough ratings");
156        assert!(error.to_string().contains("Insufficient data"));
157    }
158
159    #[test]
160    fn test_invalid_rating_error() {
161        let error = RecommendError::InvalidRating(-1.0);
162        assert!(error.to_string().contains("Invalid rating"));
163    }
164}