1use thiserror::Error;
7
8#[derive(Debug, Error)]
10pub enum PulseHiveError {
11 #[error("Substrate error: {0}")]
15 Substrate(#[from] pulsedb::PulseDBError),
16
17 #[error("LLM error: {0}")]
19 Llm(String),
20
21 #[error("Tool error: {0}")]
23 Tool(String),
24
25 #[error("Agent error: {0}")]
27 Agent(String),
28
29 #[error("Configuration error: {0}")]
31 Config(String),
32
33 #[error("Validation error: {0}")]
35 Validation(String),
36
37 #[error("Embedding error: {0}")]
39 Embedding(String),
40}
41
42impl PulseHiveError {
43 pub fn llm(msg: impl Into<String>) -> Self {
45 Self::Llm(msg.into())
46 }
47
48 pub fn tool(msg: impl Into<String>) -> Self {
50 Self::Tool(msg.into())
51 }
52
53 pub fn agent(msg: impl Into<String>) -> Self {
55 Self::Agent(msg.into())
56 }
57
58 pub fn config(msg: impl Into<String>) -> Self {
60 Self::Config(msg.into())
61 }
62
63 pub fn validation(msg: impl Into<String>) -> Self {
65 Self::Validation(msg.into())
66 }
67
68 pub fn embedding(msg: impl Into<String>) -> Self {
70 Self::Embedding(msg.into())
71 }
72}
73
74pub type Result<T> = std::result::Result<T, PulseHiveError>;
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn test_pulsedb_error_converts_via_from() {
83 let db_err = pulsedb::PulseDBError::config("test failure");
84 let hive_err: PulseHiveError = db_err.into();
85 assert!(matches!(hive_err, PulseHiveError::Substrate(_)));
86 assert!(hive_err.to_string().contains("test failure"));
87 }
88
89 #[test]
90 fn test_question_mark_propagation() {
91 fn inner() -> Result<()> {
92 Err(pulsedb::PulseDBError::config("missing collective"))?
94 }
95
96 let result = inner();
97 assert!(result.is_err());
98 assert!(matches!(result.unwrap_err(), PulseHiveError::Substrate(_)));
99 }
100
101 #[test]
102 fn test_convenience_constructors() {
103 assert_eq!(
104 PulseHiveError::llm("timeout").to_string(),
105 "LLM error: timeout"
106 );
107 assert_eq!(
108 PulseHiveError::tool("not found").to_string(),
109 "Tool error: not found"
110 );
111 assert_eq!(
112 PulseHiveError::agent("max iterations").to_string(),
113 "Agent error: max iterations"
114 );
115 assert_eq!(
116 PulseHiveError::config("no substrate").to_string(),
117 "Configuration error: no substrate"
118 );
119 assert_eq!(
120 PulseHiveError::validation("empty content").to_string(),
121 "Validation error: empty content"
122 );
123 assert_eq!(
124 PulseHiveError::embedding("dimension mismatch").to_string(),
125 "Embedding error: dimension mismatch"
126 );
127 }
128
129 #[test]
130 fn test_implements_std_error() {
131 let err = PulseHiveError::llm("test");
132 let _: &dyn std::error::Error = &err;
133 }
134}