1use std::path::PathBuf;
6use thiserror::Error;
7
8pub type Result<T> = std::result::Result<T, GraphError>;
10
11#[derive(Error, Debug)]
15pub enum GraphError {
16 #[error("Storage error: {message}")]
18 Storage {
19 message: String,
21 #[source]
23 source: Option<Box<dyn std::error::Error + Send + Sync>>,
24 },
25
26 #[error("Node not found: {node_id}")]
28 NodeNotFound {
29 node_id: String,
31 },
32
33 #[error("Edge not found: {edge_id}")]
35 EdgeNotFound {
36 edge_id: String,
38 },
39
40 #[error("File not found: {path}")]
42 FileNotFound {
43 path: PathBuf,
45 },
46
47 #[error("Invalid operation: {message}")]
49 InvalidOperation {
50 message: String,
52 },
53
54 #[error("Serialization error: {message}")]
56 Serialization {
57 message: String,
59 #[source]
61 source: Option<Box<dyn std::error::Error + Send + Sync>>,
62 },
63
64 #[error("Property '{key}' not found on {entity_type} {entity_id}")]
66 PropertyNotFound {
67 entity_type: String,
69 entity_id: String,
71 key: String,
73 },
74
75 #[error("Property type mismatch: expected {expected}, got {actual} for key '{key}'")]
77 PropertyTypeMismatch {
78 key: String,
80 expected: String,
82 actual: String,
84 },
85}
86
87impl GraphError {
88 pub fn storage<E>(message: impl Into<String>, source: Option<E>) -> Self
90 where
91 E: std::error::Error + Send + Sync + 'static,
92 {
93 Self::Storage {
94 message: message.into(),
95 source: source.map(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>),
96 }
97 }
98
99 pub fn serialization<E>(message: impl Into<String>, source: Option<E>) -> Self
101 where
102 E: std::error::Error + Send + Sync + 'static,
103 {
104 Self::Serialization {
105 message: message.into(),
106 source: source.map(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>),
107 }
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
116 fn test_node_not_found_error() {
117 let err = GraphError::NodeNotFound {
118 node_id: "test-node-123".to_string(),
119 };
120 assert_eq!(err.to_string(), "Node not found: test-node-123");
121 }
122
123 #[test]
124 fn test_storage_error() {
125 let err = GraphError::storage("Failed to write to disk", None::<std::io::Error>);
126 assert_eq!(err.to_string(), "Storage error: Failed to write to disk");
127 }
128
129 #[test]
130 fn test_invalid_operation_error() {
131 let err = GraphError::InvalidOperation {
132 message: "Cannot add duplicate node".to_string(),
133 };
134 assert_eq!(
135 err.to_string(),
136 "Invalid operation: Cannot add duplicate node"
137 );
138 }
139
140 #[test]
141 fn test_property_not_found_error() {
142 let err = GraphError::PropertyNotFound {
143 entity_type: "node".to_string(),
144 entity_id: "node-123".to_string(),
145 key: "name".to_string(),
146 };
147 assert_eq!(
148 err.to_string(),
149 "Property 'name' not found on node node-123"
150 );
151 }
152}