mcp_runner/error.rs
1//! Error handling module for MCP Runner.
2//!
3//! This module defines the error types used throughout the library.
4//! It provides a comprehensive set of errors that can occur when
5//! working with MCP servers, along with helpful context for debugging.
6//!
7//! # Example
8//!
9//! ```
10//! use mcp_runner::{McpRunner, error::{Error, Result}};
11//!
12//! fn handle_error(result: Result<()>) {
13//! match result {
14//! Ok(_) => println!("Operation succeeded"),
15//! Err(Error::ServerNotFound(name)) => println!("Server '{}' not found in configuration", name),
16//! Err(Error::Communication(msg)) => println!("Communication error: {}", msg),
17//! Err(Error::Timeout(msg)) => println!("Operation timed out: {}", msg),
18//! Err(e) => println!("Other error: {}", e),
19//! }
20//! }
21//! ```
22use thiserror::Error;
23
24/// Errors that can occur in the mcp-runner library.
25///
26/// This enum represents all possible error types that can be returned from
27/// operations in the MCP Runner library. Each variant includes context
28/// information to help diagnose and handle the error appropriately.
29#[derive(Error, Debug)]
30pub enum Error {
31 /// Failed to parse configuration from a file or string.
32 ///
33 /// This error occurs when:
34 /// - The configuration JSON is malformed
35 /// - Required fields are missing
36 /// - Field types are incorrect
37 #[error("Failed to parse configuration: {0}")]
38 ConfigParse(String),
39
40 /// Configuration is valid JSON but contains invalid values.
41 ///
42 /// This error occurs when:
43 /// - A command doesn't exist or isn't executable
44 /// - Environment variables have invalid values
45 /// - Conflicting settings are specified
46 #[error("Invalid configuration: {0}")]
47 ConfigInvalid(String),
48
49 /// Error when starting, stopping, or communicating with a server process.
50 ///
51 /// This error occurs when:
52 /// - The process fails to start
53 /// - The process exits unexpectedly
54 /// - The process fails to respond correctly
55 #[error("Server process error: {0}")]
56 Process(String),
57
58 /// Error in the JSON-RPC protocol.
59 ///
60 /// This error occurs when:
61 /// - The server returns an error response
62 /// - The method doesn't exist
63 /// - Invalid parameters are provided
64 /// - The server response doesn't match the request
65 #[error("JSON-RPC error: {0}")]
66 JsonRpc(String),
67
68 /// Error in the transport layer.
69 ///
70 /// This error occurs when:
71 /// - The transport fails to initialize
72 /// - The transport encounters an error during operation
73 /// - The transport fails to close properly
74 #[error("Transport error: {0}")]
75 Transport(String),
76
77 /// Requested server was not found in the configuration.
78 ///
79 /// This error occurs when:
80 /// - A server name is passed that doesn't exist in the config
81 /// - A server ID is used that doesn't match any running server
82 #[error("Server not found: {0}")]
83 ServerNotFound(String),
84
85 /// Requested tool was not found on the MCP server.
86 ///
87 /// This error occurs when:
88 /// - The tool name doesn't exist on the server
89 /// - The tool is disabled or unavailable
90 #[error("Tool not found: {0}")]
91 ToolNotFound(String),
92
93 /// Requested resource was not found on the MCP server.
94 ///
95 /// This error occurs when:
96 /// - The resource URI doesn't exist
97 /// - The resource is not accessible to the client
98 #[error("Resource not found: {0}")]
99 ResourceNotFound(String),
100
101 /// Error in communication with the MCP server.
102 ///
103 /// This error occurs when:
104 /// - The server doesn't respond
105 /// - The response is malformed
106 /// - The connection is lost
107 #[error("Communication error: {0}")]
108 Communication(String),
109
110 /// Operation timed out.
111 ///
112 /// This error occurs when:
113 /// - A server takes too long to start
114 /// - A server takes too long to respond
115 /// - A response is expected but doesn't arrive within the timeout period
116 #[error("Timeout: {0}")]
117 Timeout(String),
118
119 /// The server is already running.
120 ///
121 /// This error occurs when:
122 /// - Attempting to start a server that's already running
123 #[error("Already running")]
124 AlreadyRunning,
125
126 /// The server is not running.
127 ///
128 /// This error occurs when:
129 /// - Attempting to stop a server that's not running
130 /// - Attempting to get a client for a server that's not running
131 #[error("Not running")]
132 NotRunning,
133
134 /// Error in serializing or deserializing data.
135 ///
136 /// This error occurs when:
137 /// - Arguments can't be serialized to JSON
138 /// - Results can't be deserialized from JSON
139 /// - Types don't match expected schema
140 #[error("Serialization error: {0}")]
141 Serialization(String),
142
143 /// Configuration is valid but contains values that fail validation checks.
144 ///
145 /// This error occurs when:
146 /// - A specified file path doesn't exist.
147 /// - A required field is missing based on context.
148 /// - A value is outside the allowed range or set.
149 #[error("Config validation error: {0}")]
150 ConfigValidation(String),
151
152 /// Unauthorized access error.
153 ///
154 /// This error occurs when:
155 /// - An operation requires authentication but none was provided.
156 /// - The provided authentication token is invalid.
157 /// - The authenticated user does not have permission for the operation.
158 #[error("Unauthorized: {0}")]
159 Unauthorized(String),
160
161 /// The client is already cached.
162 ///
163 /// This error occurs when:
164 /// - There is an attempt to cache a client that is already cached.
165 #[error("Client already cached")]
166 ClientAlreadyCached,
167
168 /// Any other error not covered by the above categories.
169 ///
170 /// This is a catch-all error for cases not explicitly handled elsewhere.
171 #[error("Other error: {0}")]
172 Other(String),
173}
174
175/// Result type for mcp-runner operations.
176///
177/// This is a convenience type alias for `std::result::Result` with the `Error` type
178/// from this module. Use this throughout the library and in client code to handle
179/// errors in a consistent way.
180pub type Result<T> = std::result::Result<T, Error>;