Skip to main content

bamboo_agent/
error.rs

1//! Error types for Bamboo
2//!
3//! This module defines the main error type used throughout the Bamboo application
4//! for handling various failure scenarios.
5
6use thiserror::Error;
7
8/// Main error type for Bamboo operations
9///
10/// This enum represents all possible errors that can occur when working
11/// with the Bamboo system, including configuration, I/O, serialization,
12/// HTTP server, process management, and agent-related errors.
13#[derive(Debug, Error)]
14pub enum BambooError {
15    /// Configuration-related errors (invalid settings, missing config files, etc.)
16    #[error("Configuration error: {0}")]
17    Config(String),
18
19    /// I/O errors from file system operations
20    #[error("IO error: {0}")]
21    Io(#[from] std::io::Error),
22
23    /// Serialization/deserialization errors (JSON, YAML, etc.)
24    #[error("Serialization error: {0}")]
25    Serialization(#[from] serde_json::Error),
26
27    /// HTTP server startup and runtime errors
28    #[error("HTTP server error: {0}")]
29    HttpServer(String),
30
31    /// Process management errors (spawning, monitoring, etc.)
32    #[error("Process management error: {0}")]
33    ProcessManagement(String),
34
35    /// Agent execution errors (LLM communication, tool execution, etc.)
36    #[error("Agent error: {0}")]
37    Agent(String),
38
39    /// Generic errors from anyhow
40    #[error("{0}")]
41    Other(#[from] anyhow::Error),
42}
43
44/// Convenient result type alias for Bamboo operations
45pub 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}