prism_mcp_rs/core/
enhanced_errors.rs1use std::time::Duration;
5use thiserror::Error;
6
7#[derive(Error, Debug)]
9pub enum TransportError {
10 #[error("Connection failed: {message}")]
11 ConnectionFailed { message: String },
12
13 #[error("Process start failed: {command} - {reason}")]
14 ProcessStartFailed { command: String, reason: String },
15
16 #[error("I/O operation failed: {operation}")]
17 IoError {
18 operation: String,
19 #[source]
20 source: std::io::Error,
21 },
22
23 #[error("Transport not connected")]
24 NotConnected,
25
26 #[error("Transport already closed")]
27 AlreadyClosed,
28}
29
30#[derive(Error, Debug)]
32pub enum ProtocolError {
33 #[error("Invalid message format: {message}")]
34 InvalidFormat { message: String },
35
36 #[error("Method not found: {method}")]
37 MethodNotFound { method: String },
38
39 #[error("Invalid parameters for {method}: {reason}")]
40 InvalidParameters { method: String, reason: String },
41
42 #[error("Protocol version mismatch: expected {expected}, got {actual}")]
43 VersionMismatch { expected: String, actual: String },
44}
45
46#[derive(Error, Debug)]
48pub enum McpError {
49 #[error("Transport error: {source}")]
50 Transport {
51 #[from]
52 source: TransportError,
53 },
54
55 #[error("Protocol error: {source}")]
56 Protocol {
57 #[from]
58 source: ProtocolError,
59 },
60
61 #[error("Operation timeout after {duration:?}")]
62 Timeout { duration: Duration },
63
64 #[error("Connection error: {message}")]
65 Connection { message: String },
66
67 #[error("Serialization error: {message}")]
68 Serialization { message: String },
69
70 #[error("Validation error: {message}")]
71 Validation { message: String },
72
73 #[error("Internal error: {message}")]
74 Internal { message: String },
75}
76
77pub type McpResult<T> = Result<T, McpError>;
79
80impl McpError {
82 pub fn transport(message: impl Into<String>) -> Self {
84 Self::Transport {
85 source: TransportError::ConnectionFailed {
86 message: message.into(),
87 },
88 }
89 }
90
91 pub fn protocol(message: impl Into<String>) -> Self {
93 Self::Protocol {
94 source: ProtocolError::InvalidFormat {
95 message: message.into(),
96 },
97 }
98 }
99
100 pub fn timeout(_message: impl Into<String>) -> Self {
102 Self::Timeout {
103 duration: Duration::from_secs(30), }
105 }
106
107 pub fn connection(message: impl Into<String>) -> Self {
109 Self::Connection {
110 message: message.into(),
111 }
112 }
113
114 pub fn serialization(message: impl Into<String>) -> Self {
116 Self::Serialization {
117 message: message.into(),
118 }
119 }
120
121 pub fn validation(message: impl Into<String>) -> Self {
123 Self::Validation {
124 message: message.into(),
125 }
126 }
127
128 pub fn internal(message: impl Into<String>) -> Self {
130 Self::Internal {
131 message: message.into(),
132 }
133 }
134
135 pub fn is_recoverable(&self) -> bool {
137 match self {
138 McpError::Transport { source } => matches!(
139 source,
140 TransportError::ConnectionFailed { .. } | TransportError::IoError { .. }
141 ),
142 McpError::Timeout { .. } => true,
143 McpError::Connection { .. } => true,
144 _ => false,
145 }
146 }
147}
148
149impl From<std::io::Error> for McpError {
151 fn from(err: std::io::Error) -> Self {
152 Self::Transport {
153 source: TransportError::IoError {
154 operation: "I/O operation".to_string(),
155 source: err,
156 },
157 }
158 }
159}
160
161impl From<serde_json::Error> for McpError {
163 fn from(err: serde_json::Error) -> Self {
164 Self::Serialization {
165 message: err.to_string(),
166 }
167 }
168}