1use serde::{Deserialize, Serialize};
2use thiserror::Error;
3
4#[derive(Error, Debug, Clone, Serialize, Deserialize)]
5pub enum ToolError {
6 #[error("Unknown tool: {0}")]
7 UnknownTool(String),
8
9 #[error("Invalid parameters for {0}: {1}")]
10 InvalidParams(String, String), #[error("{tool_name} failed: {message}")]
13 Execution { tool_name: String, message: String },
14
15 #[error("{0} was cancelled")]
16 Cancelled(String), #[error("{0} timed out")]
19 Timeout(String), #[error("{0} requires approval to run")]
22 DeniedByUser(String), #[error("Unexpected error: {0}")]
25 InternalError(String), #[error("File operation failed in {tool_name}: {message}")]
28 Io { tool_name: String, message: String },
29
30 #[error("Failed to process data: {0}")]
31 Serialization(String),
32
33 #[error("Network request failed: {0}")]
34 Http(String),
35
36 #[error("Invalid pattern: {0}")]
37 Regex(String),
38
39 #[error("Cannot connect to {server_name}: {message}")]
40 McpConnectionFailed {
41 server_name: String,
42 message: String,
43 },
44}
45
46impl ToolError {
47 pub fn execution<T: Into<String>, M: Into<String>>(tool_name: T, message: M) -> Self {
48 ToolError::Execution {
49 tool_name: tool_name.into(),
50 message: message.into(),
51 }
52 }
53
54 pub fn io<T: Into<String>, M: Into<String>>(tool_name: T, message: M) -> Self {
55 ToolError::Io {
56 tool_name: tool_name.into(),
57 message: message.into(),
58 }
59 }
60
61 pub fn invalid_params<T: Into<String>, M: Into<String>>(tool_name: T, message: M) -> Self {
62 ToolError::InvalidParams(tool_name.into(), message.into())
63 }
64
65 pub fn mcp_connection_failed<T: Into<String>, M: Into<String>>(
66 server_name: T,
67 message: M,
68 ) -> Self {
69 ToolError::McpConnectionFailed {
70 server_name: server_name.into(),
71 message: message.into(),
72 }
73 }
74}