1use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, EngramError>;
7
8#[derive(Error, Debug)]
10pub enum EngramError {
11 #[error("Database error: {0}")]
12 Database(#[from] rusqlite::Error),
13
14 #[error("Storage error: {0}")]
15 Storage(String),
16
17 #[error("Memory not found: {0}")]
18 NotFound(i64),
19
20 #[error("Invalid input: {0}")]
21 InvalidInput(String),
22
23 #[error("Embedding error: {0}")]
24 Embedding(String),
25
26 #[error("Search error: {0}")]
27 Search(String),
28
29 #[error("Sync error: {0}")]
30 Sync(String),
31
32 #[error("Cloud storage error: {0}")]
33 CloudStorage(String),
34
35 #[error("Encryption error: {0}")]
36 Encryption(String),
37
38 #[error("Serialization error: {0}")]
39 Serialization(#[from] serde_json::Error),
40
41 #[error("IO error: {0}")]
42 Io(#[from] std::io::Error),
43
44 #[error("HTTP request error: {0}")]
45 #[cfg(any(feature = "openai", feature = "multimodal"))]
46 Http(#[from] reqwest::Error),
47
48 #[error("HTTP request error: {0}")]
49 #[cfg(not(any(feature = "openai", feature = "multimodal")))]
50 Http(String),
51
52 #[error("Configuration error: {0}")]
53 Config(String),
54
55 #[error("Conflict: {0}")]
56 Conflict(String),
57
58 #[error("Duplicate memory detected (existing_id={existing_id}): {message}")]
59 Duplicate { existing_id: i64, message: String },
60
61 #[error("Authentication error: {0}")]
62 Auth(String),
63
64 #[error("Unauthorized: {0}")]
65 Unauthorized(String),
66
67 #[error("Rate limited: retry after {0} seconds")]
68 RateLimited(u64),
69
70 #[error("Internal error: {0}")]
71 Internal(String),
72}
73
74impl EngramError {
75 pub fn is_retryable(&self) -> bool {
77 matches!(
78 self,
79 EngramError::Sync(_)
80 | EngramError::CloudStorage(_)
81 | EngramError::Http(_)
82 | EngramError::RateLimited(_)
83 )
84 }
85
86 pub fn code(&self) -> i64 {
88 match self {
89 EngramError::NotFound(_) => -32001,
90 EngramError::InvalidInput(_) => -32602,
91 EngramError::Auth(_) => -32003,
92 EngramError::Unauthorized(_) => -32003,
93 EngramError::RateLimited(_) => -32004,
94 EngramError::Conflict(_) => -32005,
95 EngramError::Duplicate { .. } => -32006,
96 _ => -32000,
97 }
98 }
99}