Skip to main content

lellm_core/
error.rs

1//! 错误类型定义。
2
3use thiserror::Error;
4
5/// lellm 顶层错误类型。
6#[derive(Debug, Error)]
7pub enum LellmError {
8    #[error("LLM error: {0}")]
9    Llm(#[from] LlmError),
10    #[error("Tool error: {0}")]
11    Tool(#[from] ToolError),
12    #[error("Memory error: {0}")]
13    Memory(#[from] MemoryError),
14    #[error("Parse error: {0}")]
15    Parse(#[from] ParseError),
16}
17
18/// LLM API 错误。
19#[derive(Debug, Error)]
20pub enum LlmError {
21    #[error("api error: {provider} {status}")]
22    ApiError {
23        provider: String,
24        status: u16,
25        code: Option<String>,
26        message: String,
27    },
28
29    #[error("request timeout")]
30    Timeout,
31
32    #[error("response parse error")]
33    ParseError { detail: String },
34
35    #[error("network error")]
36    Network { detail: String },
37
38    #[error("model not found: {model}")]
39    ModelNotFound { model: String },
40
41    #[error("{message}")]
42    Other { message: String },
43}
44
45/// 工具执行错误。
46#[derive(Debug, Error)]
47pub enum ToolError {
48    #[error("tool not found: {0}")]
49    NotFound(String),
50
51    #[error("tool execution failed: {0}")]
52    ExecutionFailed(String),
53
54    #[error("tool execution timed out")]
55    Timeout,
56
57    #[error("tool call loop detected")]
58    LoopDetected,
59}
60
61/// 记忆操作错误。
62#[derive(Debug, Error)]
63pub enum MemoryError {
64    #[error("memory IO error: {0}")]
65    IoError(String),
66
67    #[error("memory database error: {0}")]
68    DatabaseError(String),
69}
70
71/// 解析错误。
72#[derive(Debug, Error)]
73#[error("parse error: {detail}")]
74pub struct ParseError {
75    pub detail: String,
76}
77
78#[cfg(test)]
79mod tests {
80    use super::*;
81
82    #[test]
83    fn test_llm_error_display() {
84        let err = LlmError::Timeout;
85        assert_eq!(format!("{}", err), "request timeout");
86    }
87
88    #[test]
89    fn test_llm_error_api_error_display() {
90        let err = LlmError::ApiError {
91            provider: "openai".into(),
92            status: 429,
93            code: Some("rate_limit".into()),
94            message: "Too many requests".into(),
95        };
96        assert!(format!("{}", err).contains("openai"));
97        assert!(format!("{}", err).contains("429"));
98    }
99
100    #[test]
101    fn test_tool_error_display() {
102        let err = ToolError::NotFound("read_file".into());
103        assert_eq!(format!("{}", err), "tool not found: read_file");
104    }
105
106    #[test]
107    fn test_lellm_error_from_llm_error() {
108        let llm_err = LlmError::Timeout;
109        let top_err: LellmError = llm_err.into();
110        assert!(format!("{}", top_err).contains("LLM error"));
111    }
112}