1use thiserror::Error;
2
3#[derive(Error, Debug)]
4#[allow(dead_code)]
5pub enum MicroClawError {
6 #[error("LLM API error: {0}")]
7 LlmApi(String),
8
9 #[error("Rate limited, retry after backoff")]
10 RateLimited,
11
12 #[error("Database error: {0}")]
13 Database(#[from] rusqlite::Error),
14
15 #[error("HTTP error: {0}")]
16 Http(#[from] reqwest::Error),
17
18 #[error("JSON error: {0}")]
19 Json(#[from] serde_json::Error),
20
21 #[error("IO error: {0}")]
22 Io(#[from] std::io::Error),
23
24 #[error("Tool execution error: {0}")]
25 ToolExecution(String),
26
27 #[error("Config error: {0}")]
28 Config(String),
29
30 #[error("Max tool iterations reached ({0})")]
31 MaxIterations(usize),
32}
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37
38 #[test]
39 fn test_error_display_messages() {
40 let e = MicroClawError::LlmApi("bad request".into());
41 assert_eq!(e.to_string(), "LLM API error: bad request");
42
43 let e = MicroClawError::RateLimited;
44 assert_eq!(e.to_string(), "Rate limited, retry after backoff");
45
46 let e = MicroClawError::ToolExecution("tool failed".into());
47 assert_eq!(e.to_string(), "Tool execution error: tool failed");
48
49 let e = MicroClawError::Config("missing key".into());
50 assert_eq!(e.to_string(), "Config error: missing key");
51
52 let e = MicroClawError::MaxIterations(25);
53 assert_eq!(e.to_string(), "Max tool iterations reached (25)");
54 }
55
56 #[test]
57 fn test_error_from_io() {
58 let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "not found");
59 let e: MicroClawError = io_err.into();
60 assert!(e.to_string().contains("not found"));
61 }
62
63 #[test]
64 fn test_error_from_json() {
65 let json_err = serde_json::from_str::<serde_json::Value>("{{invalid").unwrap_err();
66 let e: MicroClawError = json_err.into();
67 assert!(e.to_string().contains("JSON error"));
68 }
69
70 #[test]
71 fn test_error_debug() {
72 let e = MicroClawError::RateLimited;
73 let debug = format!("{:?}", e);
74 assert!(debug.contains("RateLimited"));
75 }
76}