oximedia_recommend/
error.rs1use thiserror::Error;
4
5pub type RecommendResult<T> = Result<T, RecommendError>;
7
8#[derive(Debug, Error)]
10pub enum RecommendError {
11 #[error("User not found: {0}")]
13 UserNotFound(uuid::Uuid),
14
15 #[error("Content not found: {0}")]
17 ContentNotFound(uuid::Uuid),
18
19 #[error("Insufficient data: {0}")]
21 InsufficientData(String),
22
23 #[error("Invalid rating: {0}")]
25 InvalidRating(f32),
26
27 #[error("Invalid similarity score: {0}")]
29 InvalidSimilarity(f32),
30
31 #[error("Matrix computation error: {0}")]
33 MatrixError(String),
34
35 #[error("Profile error: {0}")]
37 ProfileError(String),
38
39 #[error("History tracking error: {0}")]
41 HistoryError(String),
42
43 #[error("Trending detection error: {0}")]
45 TrendingError(String),
46
47 #[error("Personalization error: {0}")]
49 PersonalizationError(String),
50
51 #[error("Diversity enforcement error: {0}")]
53 DiversityError(String),
54
55 #[error("Ranking error: {0}")]
57 RankingError(String),
58
59 #[error("Explanation generation error: {0}")]
61 ExplanationError(String),
62
63 #[error("IO error: {0}")]
65 IoError(#[from] std::io::Error),
66
67 #[error("Serialization error: {0}")]
69 SerializationError(#[from] serde_json::Error),
70
71 #[error("Rate limited: {0}")]
73 RateLimited(String),
74
75 #[cfg(feature = "onnx")]
77 #[error("ML error: {0}")]
78 Ml(#[from] oximedia_ml::MlError),
79
80 #[error("{0}")]
82 Other(String),
83}
84
85impl RecommendError {
86 #[must_use]
88 pub fn insufficient_data(msg: impl Into<String>) -> Self {
89 Self::InsufficientData(msg.into())
90 }
91
92 #[must_use]
94 pub fn matrix_error(msg: impl Into<String>) -> Self {
95 Self::MatrixError(msg.into())
96 }
97
98 #[must_use]
100 pub fn profile_error(msg: impl Into<String>) -> Self {
101 Self::ProfileError(msg.into())
102 }
103
104 #[must_use]
106 pub fn history_error(msg: impl Into<String>) -> Self {
107 Self::HistoryError(msg.into())
108 }
109
110 #[must_use]
112 pub fn trending_error(msg: impl Into<String>) -> Self {
113 Self::TrendingError(msg.into())
114 }
115
116 #[must_use]
118 pub fn personalization_error(msg: impl Into<String>) -> Self {
119 Self::PersonalizationError(msg.into())
120 }
121
122 #[must_use]
124 pub fn diversity_error(msg: impl Into<String>) -> Self {
125 Self::DiversityError(msg.into())
126 }
127
128 #[must_use]
130 pub fn ranking_error(msg: impl Into<String>) -> Self {
131 Self::RankingError(msg.into())
132 }
133
134 #[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}