Skip to main content

crates_docs/error/
mod.rs

1//! 错误处理模块
2//!
3//! 定义应用程序错误类型和结果类型别名。
4//!
5//! # 错误类型
6//!
7//! 提供多种错误变体,涵盖初始化、配置、HTTP 请求、缓存等场景。
8//!
9//! # 示例
10//!
11//! ```rust
12//! use crates_docs::error::{Error, Result};
13//!
14//! fn may_fail() -> Result<String> {
15//!     // 可能失败的操作
16//!     Ok("success".to_string())
17//! }
18//!
19//! // 创建结构化错误
20//! fn create_config_error() -> Error {
21//!     Error::config("field_name", "invalid value")
22//! }
23//!
24//! fn create_cache_error() -> Error {
25//!     Error::cache("set", Some("key".to_string()), "operation failed")
26//! }
27//! ```
28
29use thiserror::Error;
30
31/// 应用程序错误类型
32///
33/// 包含所有可能的错误变体,使用 `thiserror` 派生宏实现 `std::error::Error`。
34#[derive(Error, Debug)]
35pub enum Error {
36    /// HTTP 请求错误
37    #[error("HTTP request failed: {method} {url} - status {status}: {message}")]
38    HttpRequest {
39        /// HTTP 方法
40        method: String,
41        /// 请求 URL
42        url: String,
43        /// HTTP 状态码
44        status: u16,
45        /// 错误消息
46        message: String,
47    },
48
49    /// 缓存操作错误
50    #[error("Cache operation '{operation}' failed for key '{key}': {message}")]
51    Cache {
52        /// 操作类型 ("get", "set", "delete", "clear")
53        operation: String,
54        /// 缓存键
55        key: String,
56        /// 错误消息
57        message: String,
58    },
59
60    /// MCP 协议错误
61    #[error("MCP protocol error in '{context}': {message}")]
62    Mcp {
63        /// 错误发生的上下文
64        context: String,
65        /// 错误消息
66        message: String,
67    },
68
69    /// 初始化错误
70    #[error("Initialization failed for '{component}': {message}")]
71    Initialization {
72        /// 初始化失败的组件
73        component: String,
74        /// 错误消息
75        message: String,
76    },
77
78    /// 配置错误
79    #[error("Configuration error for '{field}': {message}")]
80    Config {
81        /// 配置字段名
82        field: String,
83        /// 错误消息
84        message: String,
85    },
86
87    /// 解析错误
88    #[error("Parse failed for '{input}'{position}: {message}")]
89    Parse {
90        /// 解析的输入源
91        input: String,
92        /// 位置信息
93        position: String,
94        /// 错误消息
95        message: String,
96    },
97
98    /// 认证错误
99    #[error("Authentication failed for '{provider}': {message}")]
100    Auth {
101        /// 认证提供者
102        provider: String,
103        /// 错误消息
104        message: String,
105    },
106
107    /// IO 错误
108    #[error("IO error: {0}")]
109    Io(#[from] std::io::Error),
110
111    /// JSON 序列化/反序列化错误
112    #[error("JSON error: {0}")]
113    Json(#[from] serde_json::Error),
114
115    /// URL 解析错误
116    #[error("URL parse error: {0}")]
117    Url(#[from] url::ParseError),
118
119    /// Reqwest HTTP 客户端错误
120    #[error("HTTP client error: {0}")]
121    Reqwest(#[from] reqwest::Error),
122
123    /// 其他错误
124    #[error("Unknown error: {0}")]
125    Other(String),
126}
127
128/// 结果类型别名
129///
130/// `Result<T>` 是 `std::result::Result<T, Error>` 的简写。
131pub type Result<T> = std::result::Result<T, Error>;
132
133impl Error {
134    /// 创建 HTTP 请求错误
135    ///
136    /// # 参数
137    ///
138    /// * `method` - HTTP 方法 (GET, POST, 等)
139    /// * `url` - 请求的 URL
140    /// * `status` - HTTP 状态码
141    /// * `message` - 错误消息
142    #[must_use]
143    pub fn http_request(
144        method: impl Into<String>,
145        url: impl Into<String>,
146        status: u16,
147        message: impl Into<String>,
148    ) -> Self {
149        Self::HttpRequest {
150            method: method.into(),
151            url: url.into(),
152            status,
153            message: message.into(),
154        }
155    }
156
157    /// 创建缓存操作错误
158    ///
159    /// # 参数
160    ///
161    /// * `operation` - 操作类型 ("get", "set", "delete", "clear")
162    /// * `key` - 相关的缓存键(可选)
163    /// * `message` - 错误消息
164    #[must_use]
165    pub fn cache(
166        operation: impl Into<String>,
167        key: Option<String>,
168        message: impl Into<String>,
169    ) -> Self {
170        Self::Cache {
171            operation: operation.into(),
172            key: key.unwrap_or_else(|| "N/A".to_string()),
173            message: message.into(),
174        }
175    }
176
177    /// 创建 MCP 协议错误
178    ///
179    /// # 参数
180    ///
181    /// * `context` - 错误发生的上下文
182    /// * `message` - 错误消息
183    #[must_use]
184    pub fn mcp(context: impl Into<String>, message: impl Into<String>) -> Self {
185        Self::Mcp {
186            context: context.into(),
187            message: message.into(),
188        }
189    }
190
191    /// 创建初始化错误
192    ///
193    /// # 参数
194    ///
195    /// * `component` - 初始化失败的组件
196    /// * `message` - 错误消息
197    #[must_use]
198    pub fn initialization(component: impl Into<String>, message: impl Into<String>) -> Self {
199        Self::Initialization {
200            component: component.into(),
201            message: message.into(),
202        }
203    }
204
205    /// 创建配置错误
206    ///
207    /// # 参数
208    ///
209    /// * `field` - 配置字段名
210    /// * `message` - 错误消息
211    #[must_use]
212    pub fn config(field: impl Into<String>, message: impl Into<String>) -> Self {
213        Self::Config {
214            field: field.into(),
215            message: message.into(),
216        }
217    }
218
219    /// 创建解析错误
220    ///
221    /// # 参数
222    ///
223    /// * `input` - 解析的输入源
224    /// * `position` - 错误位置(可选)
225    /// * `message` - 错误消息
226    #[must_use]
227    pub fn parse(
228        input: impl Into<String>,
229        position: Option<usize>,
230        message: impl Into<String>,
231    ) -> Self {
232        Self::Parse {
233            input: input.into(),
234            position: position.map_or_else(String::new, |p| format!(" at position {p}")),
235            message: message.into(),
236        }
237    }
238
239    /// 创建认证错误
240    ///
241    /// # 参数
242    ///
243    /// * `provider` - 认证提供者
244    /// * `message` - 错误消息
245    #[must_use]
246    pub fn auth(provider: impl Into<String>, message: impl Into<String>) -> Self {
247        Self::Auth {
248            provider: provider.into(),
249            message: message.into(),
250        }
251    }
252}
253
254impl From<Box<dyn std::error::Error + Send + Sync>> for Error {
255    fn from(err: Box<dyn std::error::Error + Send + Sync>) -> Self {
256        Error::Other(err.to_string())
257    }
258}
259
260impl From<anyhow::Error> for Error {
261    fn from(err: anyhow::Error) -> Self {
262        Error::Other(err.to_string())
263    }
264}