1use thiserror::Error;
7
8#[derive(Debug, Error)]
14pub enum BambooError {
15 #[error("Configuration error: {0}")]
17 Config(String),
18
19 #[error("IO error: {0}")]
21 Io(#[from] std::io::Error),
22
23 #[error("Serialization error: {0}")]
25 Serialization(#[from] serde_json::Error),
26
27 #[error("HTTP server error: {0}")]
29 HttpServer(String),
30
31 #[error("Process management error: {0}")]
33 ProcessManagement(String),
34
35 #[error("Agent error: {0}")]
37 Agent(String),
38
39 #[error("{0}")]
41 Other(#[from] anyhow::Error),
42}
43
44pub type Result<T> = std::result::Result<T, BambooError>;
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50
51 #[test]
52 fn test_bamboo_error_config() {
53 let err = BambooError::Config("Invalid setting".to_string());
54 let msg = err.to_string();
55 assert!(msg.contains("Configuration error"));
56 assert!(msg.contains("Invalid setting"));
57 }
58
59 #[test]
60 fn test_bamboo_error_http_server() {
61 let err = BambooError::HttpServer("Failed to bind".to_string());
62 let msg = err.to_string();
63 assert!(msg.contains("HTTP server error"));
64 assert!(msg.contains("Failed to bind"));
65 }
66
67 #[test]
68 fn test_bamboo_error_process_management() {
69 let err = BambooError::ProcessManagement("Process crashed".to_string());
70 let msg = err.to_string();
71 assert!(msg.contains("Process management error"));
72 assert!(msg.contains("Process crashed"));
73 }
74
75 #[test]
76 fn test_bamboo_error_agent() {
77 let err = BambooError::Agent("Tool execution failed".to_string());
78 let msg = err.to_string();
79 assert!(msg.contains("Agent error"));
80 assert!(msg.contains("Tool execution failed"));
81 }
82
83 #[test]
84 fn test_bamboo_error_from_io() {
85 let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "File not found");
86 let bamboo_err: BambooError = io_err.into();
87 assert!(matches!(bamboo_err, BambooError::Io(_)));
88 let msg = bamboo_err.to_string();
89 assert!(msg.contains("IO error"));
90 }
91
92 #[test]
93 fn test_bamboo_error_from_serde_json() {
94 let json_err = serde_json::from_str::<i32>("invalid");
95 assert!(json_err.is_err());
96 let bamboo_err: BambooError = json_err.unwrap_err().into();
97 assert!(matches!(bamboo_err, BambooError::Serialization(_)));
98 let msg = bamboo_err.to_string();
99 assert!(msg.contains("Serialization error"));
100 }
101
102 #[test]
103 fn test_bamboo_error_from_anyhow() {
104 let anyhow_err = anyhow::anyhow!("Something went wrong");
105 let bamboo_err: BambooError = anyhow_err.into();
106 assert!(matches!(bamboo_err, BambooError::Other(_)));
107 let msg = bamboo_err.to_string();
108 assert!(msg.contains("Something went wrong"));
109 }
110
111 #[test]
112 fn test_bamboo_error_debug() {
113 let err = BambooError::Config("test".to_string());
114 let debug_str = format!("{:?}", err);
115 assert!(debug_str.contains("Config"));
116 }
117
118 #[test]
119 fn test_result_ok() {
120 let result: Result<String> = Ok("success".to_string());
121 assert!(result.is_ok());
122 }
123
124 #[test]
125 fn test_result_err() {
126 let result: Result<String> = Err(BambooError::Config("error".to_string()));
127 assert!(result.is_err());
128 }
129
130 #[test]
131 fn test_bamboo_error_io_from() {
132 let err = std::io::Error::new(std::io::ErrorKind::PermissionDenied, "Access denied");
133 let bamboo_err = BambooError::from(err);
134 assert!(matches!(bamboo_err, BambooError::Io(_)));
135 }
136
137 #[test]
138 fn test_bamboo_error_chain() {
139 let inner = anyhow::anyhow!("Inner error");
140 let outer = BambooError::Other(inner);
141 assert!(outer.to_string().contains("Inner error"));
142 }
143}