Skip to main content

smcp_computer/
errors.rs

1/*!
2* 文件名: errors.rs
3* 作者: JQQ
4* 创建日期: 2025/12/15
5* 最后修改日期: 2025/12/15
6* 版权: 2023 JQQ. All rights reserved.
7* 依赖: thiserror
8* 描述: Computer模块的错误定义 / Error definitions for Computer module
9*/
10
11use thiserror::Error;
12
13/// Computer模块的Result类型别名 / Result type alias for Computer module
14pub type ComputerResult<T> = Result<T, ComputerError>;
15
16/// Computer模块的错误类型 / Error type for Computer module
17#[derive(Debug, Error)]
18pub enum ComputerError {
19    #[error("Tool name duplicated: {tool_name} in servers: {servers:?}")]
20    /// 工具名称重复 / Tool name duplicated
21    ToolNameDuplicated {
22        tool_name: String,
23        servers: Vec<String>,
24    },
25
26    #[error("Input not found: {input_id}")]
27    /// 输入项未找到 / Input not found
28    InputNotFound { input_id: String },
29
30    #[error("Server {server_name} is not active")]
31    /// 服务器未激活 / Server not active
32    ServerNotActive { server_name: String },
33
34    #[error("VRL syntax error: {message}")]
35    /// VRL语法错误 / VRL syntax error
36    VrlSyntaxError { message: String },
37
38    #[error("Tool execution timeout after {timeout}s")]
39    /// 工具执行超时 / Tool execution timeout
40    ToolExecutionTimeout { timeout: u64 },
41
42    #[error("MCP client error: {0}")]
43    /// MCP客户端错误 / MCP client error
44    McpClientError(#[from] McpClientError),
45
46    #[error("IO error: {0}")]
47    /// IO错误 / IO error
48    IoError(#[from] std::io::Error),
49
50    #[error("Serialization error: {0}")]
51    /// 序列化错误 / Serialization error
52    SerializationError(#[from] serde_json::Error),
53
54    #[error("Transport error: {0}")]
55    /// 传输层错误 / Transport error
56    TransportError(String),
57
58    #[error("Invalid configuration: {0}")]
59    /// 无效配置 / Invalid configuration
60    InvalidConfiguration(String),
61
62    #[error("Connection error: {0}")]
63    /// 连接错误 / Connection error
64    ConnectionError(String),
65
66    #[error("Runtime error: {0}")]
67    /// 运行时错误 / Runtime error
68    RuntimeError(String),
69
70    #[error("Permission error: {0}")]
71    /// 权限错误 / Permission error
72    PermissionError(String),
73
74    #[error("Timeout error: {0}")]
75    /// 超时错误 / Timeout error
76    TimeoutError(String),
77
78    #[error("Protocol error: {0}")]
79    /// 协议错误 / Protocol error
80    ProtocolError(String),
81
82    #[error("Socket.IO error: {0}")]
83    /// Socket.IO错误 / Socket.IO error
84    SocketIoError(String),
85
86    #[error("Validation error: {0}")]
87    /// 验证错误 / Validation error
88    ValidationError(String),
89
90    #[error("Invalid state: {0}")]
91    /// 无效状态 / Invalid state
92    InvalidState(String),
93
94    #[error("Render error: {0}")]
95    /// 渲染错误 / Render error
96    RenderError(String),
97}
98
99impl From<Box<dyn std::error::Error + Send + Sync>> for ComputerError {
100    fn from(err: Box<dyn std::error::Error + Send + Sync>) -> Self {
101        ComputerError::RuntimeError(err.to_string())
102    }
103}
104
105impl From<crate::mcp_clients::RenderError> for ComputerError {
106    fn from(err: crate::mcp_clients::RenderError) -> Self {
107        ComputerError::RenderError(err.to_string())
108    }
109}
110
111impl ComputerError {
112    /// 获取错误码 / Get error code
113    /// 参考 A2C-SMCP 协议错误码规范 / Reference A2C-SMCP protocol error code spec
114    pub fn error_code(&self) -> i32 {
115        match self {
116            // 工具相关错误 / Tool related errors
117            ComputerError::ToolNameDuplicated { .. } => 4002, // TOOL_DISABLED
118            ComputerError::ToolExecutionTimeout { .. } => 4004, // TOOL_TIMEOUT
119
120            // 输入相关错误 / Input related errors
121            ComputerError::InputNotFound { .. } => 404, // NOT_FOUND
122
123            // 服务器相关错误 / Server related errors
124            ComputerError::ServerNotActive { .. } => 404, // NOT_FOUND
125
126            // 语法/验证错误 / Syntax/Validation errors
127            ComputerError::VrlSyntaxError { .. } => 400, // BAD_REQUEST
128            ComputerError::ValidationError(_) => 400,    // BAD_REQUEST
129            ComputerError::InvalidConfiguration(_) => 400, // BAD_REQUEST
130            ComputerError::RenderError(_) => 400,        // BAD_REQUEST
131
132            // 连接错误 / Connection errors
133            ComputerError::ConnectionError(_) => 500, // INTERNAL_ERROR
134            ComputerError::TransportError(_) => 500,  // INTERNAL_ERROR
135            ComputerError::SocketIoError(_) => 500,   // INTERNAL_ERROR
136
137            // 超时错误 / Timeout errors
138            ComputerError::TimeoutError(_) => 408, // TIMEOUT
139
140            // 权限错误 / Permission errors
141            ComputerError::PermissionError(_) => 403, // FORBIDDEN
142
143            // 协议错误 / Protocol errors
144            ComputerError::ProtocolError(_) => 500, // INTERNAL_ERROR
145
146            // 状态错误 / State errors
147            ComputerError::InvalidState(_) => 400, // BAD_REQUEST
148
149            // MCP客户端错误 / MCP client errors
150            ComputerError::McpClientError(e) => e.error_code(),
151
152            // IO和序列化错误 / IO and serialization errors
153            ComputerError::IoError(_) => 500, // INTERNAL_ERROR
154            ComputerError::SerializationError(_) => 400, // BAD_REQUEST
155
156            // 运行时错误 / Runtime errors
157            ComputerError::RuntimeError(_) => 500, // INTERNAL_ERROR
158        }
159    }
160}
161
162impl McpClientError {
163    /// 获取错误码 / Get error code
164    pub fn error_code(&self) -> i32 {
165        match self {
166            McpClientError::NotConnected => 500,        // INTERNAL_ERROR
167            McpClientError::ConnectionFailed(_) => 500, // INTERNAL_ERROR
168            McpClientError::ConnectionError(_) => 500,  // INTERNAL_ERROR
169            McpClientError::ToolCallFailed(_) => 4003,  // TOOL_EXECUTION_FAILED
170            McpClientError::InvalidState(_) => 400,     // BAD_REQUEST
171            McpClientError::ProcessError(_) => 500,     // INTERNAL_ERROR
172            McpClientError::TimeoutError(_) => 408,     // TIMEOUT
173            McpClientError::ProtocolError(_) => 500,    // INTERNAL_ERROR
174            McpClientError::ToolError(_) => 4003,       // TOOL_EXECUTION_FAILED
175            McpClientError::ConfigError(_) => 400,      // BAD_REQUEST
176            McpClientError::InternalError(_) => 500,    // INTERNAL_ERROR
177        }
178    }
179}
180
181/// MCP客户端错误 / MCP client error
182#[derive(Debug, Error)]
183pub enum McpClientError {
184    #[error("Not connected to server")]
185    /// 未连接到服务器 / Not connected
186    NotConnected,
187
188    #[error("Connection failed: {0}")]
189    /// 连接失败 / Connection failed
190    ConnectionFailed(String),
191
192    #[error("Connection error: {0}")]
193    /// 连接错误 / Connection error
194    ConnectionError(String),
195
196    #[error("Tool call failed: {0}")]
197    /// 工具调用失败 / Tool call failed
198    ToolCallFailed(String),
199
200    #[error("Invalid state: {0}")]
201    /// 无效状态 / Invalid state
202    InvalidState(String),
203
204    #[error("Process error: {0}")]
205    /// 进程错误 / Process error
206    ProcessError(String),
207
208    #[error("Timeout error: {0}")]
209    /// 超时错误 / Timeout error
210    TimeoutError(String),
211
212    #[error("Protocol error: {0}")]
213    /// 协议错误 / Protocol error
214    ProtocolError(String),
215
216    #[error("Tool error: {0}")]
217    /// 工具错误 / Tool error
218    ToolError(String),
219
220    #[error("Config error: {0}")]
221    /// 配置错误 / Config error
222    ConfigError(String),
223
224    #[error("Internal error: {0}")]
225    /// 内部错误 / Internal error
226    InternalError(String),
227}