use std::fmt;
#[derive(Debug)]
pub enum McpError {
ParseError,
InvalidRequest(String),
SerializationError,
ShutdownTimeout,
ShutdownError(String),
MethodNotFound,
InvalidParams,
InternalError(String),
NotConnected,
ConnectionClosed,
RequestTimeout,
ResourceNotFound(String),
InvalidResource(String),
AccessDenied(String),
IoError,
CapabilityNotSupported(String),
ToolExecutionError(String),
Custom { code: i32, message: String },
ConnectionFailed,
ConnectionTimeout,
ServerError(String),
}
impl McpError {
pub fn code(&self) -> i32 {
match self {
McpError::ParseError => -32700,
McpError::InvalidRequest(_) => -32600,
McpError::SerializationError => -32603,
McpError::MethodNotFound => -32601,
McpError::InvalidParams => -32602,
McpError::InternalError(_) => -32603,
McpError::NotConnected => -32000,
McpError::ConnectionClosed => -32001,
McpError::RequestTimeout => -32002,
McpError::ShutdownTimeout => -32001,
McpError::ShutdownError(_) => -32002,
McpError::ResourceNotFound(_) => -32003,
McpError::InvalidResource(_) => -32004,
McpError::IoError => -32005,
McpError::CapabilityNotSupported(_) => -32006,
McpError::AccessDenied(_) => -32007,
McpError::ToolExecutionError(_) => -32008,
McpError::Custom { code, .. } => *code,
McpError::ConnectionFailed => -32009,
McpError::ConnectionTimeout => -32010,
McpError::ServerError(_) => -32011,
}
}
}
impl fmt::Display for McpError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
McpError::ParseError => write!(f, "Parse error"),
McpError::InvalidRequest(s) => write!(f, "Invalid request: {}", s),
McpError::MethodNotFound => write!(f, "Method not found"),
McpError::InvalidParams => write!(f, "Invalid parameters"),
McpError::InternalError(s) => write!(f, "Internal error: {}", s),
McpError::NotConnected => write!(f, "Not connected"),
McpError::ConnectionClosed => write!(f, "NConnection closed"),
McpError::RequestTimeout => write!(f, "Request timeout"),
McpError::IoError => write!(f, "io error"),
McpError::SerializationError => write!(f, "Serialization error"),
McpError::ResourceNotFound(s) => write!(f, " {} Resource not found", s),
McpError::InvalidResource(s) => write!(f, "{} Invalid resource", s),
McpError::AccessDenied(s) => write!(f, "Access denied: {}", s),
McpError::ToolExecutionError(s) => write!(f, "Tool execution error: {}", s),
McpError::CapabilityNotSupported(s) => write!(f, "Capability not supported: {}", s),
McpError::ShutdownTimeout => write!(f, "Shutdown timed out"),
McpError::ShutdownError(msg) => write!(f, "Shutdown error: {}", msg),
McpError::Custom { code, message } => write!(f, "Error {}: {}", code, message),
McpError::ConnectionFailed => write!(f, "Connection failed"),
McpError::ConnectionTimeout => write!(f, "Connection timed out"),
McpError::ServerError(msg) => write!(f, "Server error: {}", msg),
}
}
}
impl std::error::Error for McpError {}
impl From<serde_json::Error> for McpError {
fn from(_error: serde_json::Error) -> Self {
McpError::SerializationError
}
}
impl From<std::io::Error> for McpError {
fn from(error: std::io::Error) -> Self {
tracing::error!("IO error: {}", error);
McpError::IoError
}
}
impl From<tokio::time::error::Elapsed> for McpError {
fn from(_error: tokio::time::error::Elapsed) -> Self {
McpError::RequestTimeout
}
}