Skip to main content

zapmyco_core/
agent_error.rs

1//! Core 层错误类型。
2
3use std::fmt;
4
5/// Agent 核心循环错误
6#[derive(Debug)]
7pub enum AgentError {
8    /// API 调用失败
9    Api(String),
10    /// 工具执行失败
11    ToolExecution { name: String, error: String },
12    /// 达到最大工具调用轮次
13    MaxRoundsReached,
14    /// 事件通道关闭
15    ChannelClosed,
16    /// 消息转换失败
17    Conversion(String),
18}
19
20impl fmt::Display for AgentError {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        match self {
23            AgentError::Api(msg) => write!(f, "API error: {}", msg),
24            AgentError::ToolExecution { name, error } => {
25                write!(f, "tool '{}' execution error: {}", name, error)
26            }
27            AgentError::MaxRoundsReached => {
28                write!(f, "max tool rounds reached")
29            }
30            AgentError::ChannelClosed => {
31                write!(f, "event channel closed")
32            }
33            AgentError::Conversion(msg) => {
34                write!(f, "conversion error: {}", msg)
35            }
36        }
37    }
38}
39
40impl std::error::Error for AgentError {}
41
42// 允许从 String 快速创建 API 错误
43impl From<String> for AgentError {
44    fn from(msg: String) -> Self {
45        AgentError::Api(msg)
46    }
47}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    #[test]
54    fn test_display_api() {
55        let err = AgentError::Api("timeout".to_string());
56        assert_eq!(format!("{}", err), "API error: timeout");
57    }
58
59    #[test]
60    fn test_display_tool_execution() {
61        let err = AgentError::ToolExecution {
62            name: "read".to_string(),
63            error: "not found".to_string(),
64        };
65        assert_eq!(format!("{}", err), "tool 'read' execution error: not found");
66    }
67
68    #[test]
69    fn test_display_max_rounds() {
70        let err = AgentError::MaxRoundsReached;
71        assert_eq!(format!("{}", err), "max tool rounds reached");
72    }
73
74    #[test]
75    fn test_display_channel_closed() {
76        let err = AgentError::ChannelClosed;
77        assert_eq!(format!("{}", err), "event channel closed");
78    }
79
80    #[test]
81    fn test_display_conversion() {
82        let err = AgentError::Conversion("bad format".to_string());
83        assert_eq!(format!("{}", err), "conversion error: bad format");
84    }
85
86    #[test]
87    fn test_error_impl() {
88        let err = AgentError::MaxRoundsReached;
89        assert!(std::error::Error::source(&err).is_none());
90    }
91
92    #[test]
93    fn test_from_string() {
94        let err: AgentError = "oops".to_string().into();
95        assert!(matches!(err, AgentError::Api(_)));
96    }
97}