1use std::fmt;
6use std::error::Error;
7
8pub type Result<T> = std::result::Result<T, PhagoError>;
10
11#[derive(Debug, Clone)]
13pub enum PhagoError {
14 Document(DocumentError),
16 Graph(GraphError),
18 Agent(AgentError),
20 Session(SessionError),
22 Query(QueryError),
24 Config(ConfigError),
26 Io(String),
28 Serialization(String),
30}
31
32impl fmt::Display for PhagoError {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 match self {
35 PhagoError::Document(e) => write!(f, "Document error: {}", e),
36 PhagoError::Graph(e) => write!(f, "Graph error: {}", e),
37 PhagoError::Agent(e) => write!(f, "Agent error: {}", e),
38 PhagoError::Session(e) => write!(f, "Session error: {}", e),
39 PhagoError::Query(e) => write!(f, "Query error: {}", e),
40 PhagoError::Config(e) => write!(f, "Config error: {}", e),
41 PhagoError::Io(msg) => write!(f, "I/O error: {}", msg),
42 PhagoError::Serialization(msg) => write!(f, "Serialization error: {}", msg),
43 }
44 }
45}
46
47impl Error for PhagoError {}
48
49impl From<std::io::Error> for PhagoError {
50 fn from(e: std::io::Error) -> Self {
51 PhagoError::Io(e.to_string())
52 }
53}
54
55impl From<serde_json::Error> for PhagoError {
56 fn from(e: serde_json::Error) -> Self {
57 PhagoError::Serialization(e.to_string())
58 }
59}
60
61#[derive(Debug, Clone)]
63pub enum DocumentError {
64 NotFound(String),
66 AlreadyDigested(String),
68 EmptyContent,
70 InvalidFormat(String),
72}
73
74impl fmt::Display for DocumentError {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 match self {
77 DocumentError::NotFound(id) => write!(f, "Document not found: {}", id),
78 DocumentError::AlreadyDigested(id) => write!(f, "Document already digested: {}", id),
79 DocumentError::EmptyContent => write!(f, "Document content is empty"),
80 DocumentError::InvalidFormat(msg) => write!(f, "Invalid document format: {}", msg),
81 }
82 }
83}
84
85#[derive(Debug, Clone)]
87pub enum GraphError {
88 NodeNotFound(String),
90 EdgeNotFound(String, String),
92 DuplicateNode(String),
94 InvalidWeight(f64),
96 EmptyGraph,
98}
99
100impl fmt::Display for GraphError {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 match self {
103 GraphError::NodeNotFound(id) => write!(f, "Node not found: {}", id),
104 GraphError::EdgeNotFound(from, to) => write!(f, "Edge not found: {} -> {}", from, to),
105 GraphError::DuplicateNode(label) => write!(f, "Duplicate node: {}", label),
106 GraphError::InvalidWeight(w) => write!(f, "Invalid weight: {} (must be 0.0-1.0)", w),
107 GraphError::EmptyGraph => write!(f, "Graph is empty"),
108 }
109 }
110}
111
112#[derive(Debug, Clone)]
114pub enum AgentError {
115 NotFound(String),
117 AlreadyExists(String),
119 Busy(String),
121 Dead(String),
123 InvalidAction(String),
125}
126
127impl fmt::Display for AgentError {
128 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129 match self {
130 AgentError::NotFound(id) => write!(f, "Agent not found: {}", id),
131 AgentError::AlreadyExists(id) => write!(f, "Agent already exists: {}", id),
132 AgentError::Busy(id) => write!(f, "Agent is busy: {}", id),
133 AgentError::Dead(id) => write!(f, "Agent is dead: {}", id),
134 AgentError::InvalidAction(msg) => write!(f, "Invalid action: {}", msg),
135 }
136 }
137}
138
139#[derive(Debug, Clone)]
141pub enum SessionError {
142 NotFound(String),
144 Corrupt(String),
146 VersionMismatch { expected: String, found: String },
148 SaveFailed(String),
150 LoadFailed(String),
152}
153
154impl fmt::Display for SessionError {
155 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156 match self {
157 SessionError::NotFound(path) => write!(f, "Session not found: {}", path),
158 SessionError::Corrupt(msg) => write!(f, "Session file corrupt: {}", msg),
159 SessionError::VersionMismatch { expected, found } => {
160 write!(f, "Version mismatch: expected {}, found {}", expected, found)
161 }
162 SessionError::SaveFailed(msg) => write!(f, "Save failed: {}", msg),
163 SessionError::LoadFailed(msg) => write!(f, "Load failed: {}", msg),
164 }
165 }
166}
167
168#[derive(Debug, Clone)]
170pub enum QueryError {
171 EmptyQuery,
173 NoResults,
175 InvalidParameters(String),
177 Timeout,
179}
180
181impl fmt::Display for QueryError {
182 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
183 match self {
184 QueryError::EmptyQuery => write!(f, "Query is empty"),
185 QueryError::NoResults => write!(f, "No results found"),
186 QueryError::InvalidParameters(msg) => write!(f, "Invalid parameters: {}", msg),
187 QueryError::Timeout => write!(f, "Query timed out"),
188 }
189 }
190}
191
192#[derive(Debug, Clone)]
194pub enum ConfigError {
195 InvalidValue { field: String, value: String, reason: String },
197 MissingField(String),
199 OutOfRange { field: String, min: f64, max: f64, value: f64 },
201}
202
203impl fmt::Display for ConfigError {
204 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
205 match self {
206 ConfigError::InvalidValue { field, value, reason } => {
207 write!(f, "Invalid value for {}: {} ({})", field, value, reason)
208 }
209 ConfigError::MissingField(field) => write!(f, "Missing required field: {}", field),
210 ConfigError::OutOfRange { field, min, max, value } => {
211 write!(f, "{} out of range: {} (must be {}-{})", field, value, min, max)
212 }
213 }
214 }
215}
216
217impl PhagoError {
219 pub fn document_not_found(id: impl Into<String>) -> Self {
220 PhagoError::Document(DocumentError::NotFound(id.into()))
221 }
222
223 pub fn node_not_found(id: impl Into<String>) -> Self {
224 PhagoError::Graph(GraphError::NodeNotFound(id.into()))
225 }
226
227 pub fn agent_not_found(id: impl Into<String>) -> Self {
228 PhagoError::Agent(AgentError::NotFound(id.into()))
229 }
230
231 pub fn empty_query() -> Self {
232 PhagoError::Query(QueryError::EmptyQuery)
233 }
234
235 pub fn invalid_config(field: impl Into<String>, value: impl Into<String>, reason: impl Into<String>) -> Self {
236 PhagoError::Config(ConfigError::InvalidValue {
237 field: field.into(),
238 value: value.into(),
239 reason: reason.into(),
240 })
241 }
242}