mcp_sdk_rs/
error.rs

1//! Error types for the MCP protocol.
2//!
3//! This module defines the error types and codes used in the MCP protocol.
4//! The error codes follow the JSON-RPC 2.0 specification with some additional
5//! MCP-specific error codes.
6
7use std::fmt;
8use thiserror::Error;
9
10/// Error codes as defined in the MCP protocol.
11///
12/// These error codes are based on the JSON-RPC 2.0 specification with additional
13/// MCP-specific error codes in the -32000 to -32099 range.
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15#[repr(i32)]
16pub enum ErrorCode {
17    /// Invalid JSON was received by the server.
18    /// An error occurred on the server while parsing the JSON text.
19    ParseError = -32700,
20
21    /// The JSON sent is not a valid Request object.
22    InvalidRequest = -32600,
23
24    /// The method does not exist / is not available.
25    MethodNotFound = -32601,
26
27    /// Invalid method parameter(s).
28    InvalidParams = -32602,
29
30    /// Internal JSON-RPC error.
31    InternalError = -32603,
32
33    /// Server has not been initialized.
34    /// This error is returned when a request is made before the server
35    /// has been properly initialized.
36    ServerNotInitialized = -32002,
37
38    /// Unknown error code.
39    /// This error is returned when an error code is received that is not
40    /// recognized by the implementation.
41    UnknownErrorCode = -32001,
42
43    /// Request failed.
44    /// This error is returned when a request fails for a reason not covered
45    /// by other error codes.
46    RequestFailed = -32000,
47}
48
49impl From<i32> for ErrorCode {
50    fn from(code: i32) -> Self {
51        match code {
52            -32700 => ErrorCode::ParseError,
53            -32600 => ErrorCode::InvalidRequest,
54            -32601 => ErrorCode::MethodNotFound,
55            -32602 => ErrorCode::InvalidParams,
56            -32603 => ErrorCode::InternalError,
57            -32002 => ErrorCode::ServerNotInitialized,
58            -32001 => ErrorCode::UnknownErrorCode,
59            -32000 => ErrorCode::RequestFailed,
60            _ => ErrorCode::UnknownErrorCode,
61        }
62    }
63}
64
65impl From<ErrorCode> for i32 {
66    fn from(code: ErrorCode) -> Self {
67        code as i32
68    }
69}
70
71impl fmt::Display for ErrorCode {
72    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73        write!(f, "{:?}", self)
74    }
75}
76
77/// Main error type for MCP operations
78#[derive(Error, Debug, Clone)]
79pub enum Error {
80    /// Protocol error with code and message
81    #[error("MCP protocol error: {code:?} - {message}")]
82    Protocol {
83        /// The error code
84        code: ErrorCode,
85        /// A message providing more details about the error
86        message: String,
87        /// Optional additional data about the error
88        data: Option<serde_json::Value>,
89    },
90
91    /// Transport-related errors
92    #[error("Transport error: {0}")]
93    Transport(String),
94
95    /// Serialization/deserialization errors
96    #[error("Serialization error: {0}")]
97    Serialization(String),
98
99    /// IO-related errors
100    #[error("IO error: {0}")]
101    Io(String),
102
103    /// Other miscellaneous errors
104    #[error("Other error: {0}")]
105    Other(String),
106}
107
108impl Error {
109    /// Create a new protocol error.
110    ///
111    /// # Arguments
112    ///
113    /// * `code` - The error code
114    /// * `message` - A message describing the error
115    pub fn protocol(code: ErrorCode, message: impl Into<String>) -> Self {
116        Error::Protocol {
117            code,
118            message: message.into(),
119            data: None,
120        }
121    }
122
123    /// Create a new error with additional data.
124    ///
125    /// # Arguments
126    ///
127    /// * `data` - Additional data to attach to the error
128    pub fn with_data(self, data: serde_json::Value) -> Self {
129        match self {
130            Error::Protocol {
131                code,
132                message,
133                data: _,
134            } => Error::Protocol {
135                code,
136                message,
137                data: Some(data),
138            },
139            _ => self,
140        }
141    }
142}
143
144impl From<std::io::Error> for Error {
145    fn from(err: std::io::Error) -> Self {
146        Error::Io(err.to_string())
147    }
148}
149
150impl From<serde_json::Error> for Error {
151    fn from(err: serde_json::Error) -> Self {
152        Error::Serialization(err.to_string())
153    }
154}