rust_mcp_transport/
error.rs1use crate::schema::{schema_utils::SdkError, RpcError};
2use crate::utils::CancellationError;
3use core::fmt;
4#[cfg(any(feature = "sse", feature = "streamable-http"))]
5use reqwest::Error as ReqwestError;
6#[cfg(any(feature = "sse", feature = "streamable-http"))]
7use reqwest::StatusCode;
8use std::any::Any;
9use std::io::Error as IoError;
10use thiserror::Error;
11use tokio::sync::{broadcast, mpsc};
12#[derive(Debug)]
15pub struct GenericSendError {
16 inner: Box<dyn Any + Send>,
17}
18
19#[allow(unused)]
20impl GenericSendError {
21 pub fn new<T: Send + 'static>(error: mpsc::error::SendError<T>) -> Self {
22 Self {
23 inner: Box::new(error),
24 }
25 }
26
27 fn downcast<T: Send + 'static>(self) -> Option<broadcast::error::SendError<T>> {
32 self.inner
33 .downcast::<broadcast::error::SendError<T>>()
34 .ok()
35 .map(|boxed| *boxed)
36 }
37}
38
39impl fmt::Display for GenericSendError {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 write!(f, "Broadcast SendError: Failed to send a message.")
42 }
43}
44impl std::error::Error for GenericSendError {}
46
47#[derive(Debug)]
50pub struct GenericWatchSendError {
51 inner: Box<dyn Any + Send>,
52}
53
54#[allow(unused)]
55impl GenericWatchSendError {
56 pub fn new<T: Send + 'static>(error: tokio::sync::watch::error::SendError<T>) -> Self {
57 Self {
58 inner: Box::new(error),
59 }
60 }
61
62 fn downcast<T: Send + 'static>(self) -> Option<tokio::sync::watch::error::SendError<T>> {
67 self.inner
68 .downcast::<tokio::sync::watch::error::SendError<T>>()
69 .ok()
70 .map(|boxed| *boxed)
71 }
72}
73
74impl fmt::Display for GenericWatchSendError {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 write!(f, "Watch SendError: Failed to send a message.")
77 }
78}
79impl std::error::Error for GenericWatchSendError {}
81
82pub type TransportResult<T> = core::result::Result<T, TransportError>;
83
84#[derive(Debug, Error)]
85pub enum TransportError {
86 #[error("Session expired or not found")]
87 SessionExpired,
88
89 #[error("Failed to open SSE stream: {0}")]
90 FailedToOpenSSEStream(String),
91
92 #[error("Unexpected content type: '{0}'")]
93 UnexpectedContentType(String),
94
95 #[error("Failed to send message: {0}")]
96 SendFailure(String),
97
98 #[error("I/O error: {0}")]
99 Io(#[from] IoError),
100
101 #[cfg(any(feature = "sse", feature = "streamable-http"))]
102 #[error("HTTP connection error: {0}")]
103 HttpConnection(#[from] ReqwestError),
104
105 #[cfg(any(feature = "sse", feature = "streamable-http"))]
106 #[error("HTTP error: {0}")]
107 Http(StatusCode),
108
109 #[error("SDK error: {0}")]
110 Sdk(#[from] SdkError),
111
112 #[error("Operation cancelled: {0}")]
113 Cancelled(#[from] CancellationError),
114
115 #[error("Channel closed: {0}")]
116 ChannelClosed(#[from] tokio::sync::oneshot::error::RecvError),
117
118 #[error("Configuration error: {message}")]
119 Configuration { message: String },
120
121 #[error("{0}")]
122 SendError(#[from] GenericSendError),
123
124 #[error("{0}")]
125 JsonrpcError(#[from] RpcError),
126
127 #[error("Process error: {0}")]
128 ProcessError(String),
129
130 #[error("Internal error: {0}")]
131 Internal(String),
132
133 #[error("Shutdown timed out")]
134 ShutdownTimeout,
135}