feat: keep internal error in worker's quit reason (#372)
* feat: support downcast WorkerQuitReason::Fatal * feat(transport): expose internal worker error in fatal * Update crates/rmcp/src/transport/streamable_http_client.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update crates/rmcp/src/transport/streamable_http_client.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
parent
28f4781332
commit
0a2f77de41
1 changed files with 71 additions and 40 deletions
|
|
@ -33,15 +33,17 @@ pub enum StreamableHttpError<E: std::error::Error + Send + Sync + 'static> {
|
|||
#[error("Unexpected content type: {0:?}")]
|
||||
UnexpectedContentType(Option<String>),
|
||||
#[error("Server does not support SSE")]
|
||||
SeverDoesNotSupportSse,
|
||||
ServerDoesNotSupportSse,
|
||||
#[error("Server does not support delete session")]
|
||||
SeverDoesNotSupportDeleteSession,
|
||||
ServerDoesNotSupportDeleteSession,
|
||||
#[error("Tokio join error: {0}")]
|
||||
TokioJoinError(#[from] tokio::task::JoinError),
|
||||
#[error("Deserialize error: {0}")]
|
||||
Deserialize(#[from] serde_json::Error),
|
||||
#[error("Transport channel closed")]
|
||||
TransportChannelClosed,
|
||||
#[error("Missing session id in HTTP response")]
|
||||
MissingSessionIdInResponse,
|
||||
#[cfg(feature = "auth")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "auth")))]
|
||||
#[error("Auth error: {0}")]
|
||||
|
|
@ -54,6 +56,11 @@ impl From<reqwest::Error> for StreamableHttpError<reqwest::Error> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Error)]
|
||||
pub enum StreamableHttpProtocolError {
|
||||
#[error("Missing session id in response")]
|
||||
MissingSessionIdInResponse,
|
||||
}
|
||||
pub enum StreamableHttpPostResponse {
|
||||
Accepted,
|
||||
Json(ServerJsonRpcMessage, Option<String>),
|
||||
|
|
@ -261,7 +268,7 @@ impl<C: StreamableHttpClient> Worker for StreamableHttpClientWorker<C> {
|
|||
async fn run(
|
||||
self,
|
||||
mut context: super::worker::WorkerContext<Self>,
|
||||
) -> Result<(), WorkerQuitReason> {
|
||||
) -> Result<(), WorkerQuitReason<Self::Error>> {
|
||||
let channel_buffer_capacity = self.config.channel_buffer_capacity;
|
||||
let (sse_worker_tx, mut sse_worker_rx) =
|
||||
tokio::sync::mpsc::channel::<ServerJsonRpcMessage>(channel_buffer_capacity);
|
||||
|
|
@ -278,7 +285,7 @@ impl<C: StreamableHttpClient> Worker for StreamableHttpClientWorker<C> {
|
|||
.post_message(config.uri.clone(), initialize_request, None, None)
|
||||
.await
|
||||
.map_err(WorkerQuitReason::fatal_context("send initialize request"))?
|
||||
.expect_initialized::<Self::Error>()
|
||||
.expect_initialized::<C::Error>()
|
||||
.await
|
||||
.map_err(WorkerQuitReason::fatal_context(
|
||||
"process initialize response",
|
||||
|
|
@ -288,7 +295,7 @@ impl<C: StreamableHttpClient> Worker for StreamableHttpClientWorker<C> {
|
|||
} else {
|
||||
if !self.config.allow_stateless {
|
||||
return Err(WorkerQuitReason::fatal(
|
||||
"missing session id in initialize response",
|
||||
StreamableHttpError::<C::Error>::MissingSessionIdInResponse,
|
||||
"process initialize response",
|
||||
));
|
||||
}
|
||||
|
|
@ -308,7 +315,7 @@ impl<C: StreamableHttpClient> Worker for StreamableHttpClientWorker<C> {
|
|||
Ok(_) => {
|
||||
tracing::info!(session_id = session_id.as_ref(), "delete session success")
|
||||
}
|
||||
Err(StreamableHttpError::SeverDoesNotSupportDeleteSession) => {
|
||||
Err(StreamableHttpError::ServerDoesNotSupportDeleteSession) => {
|
||||
tracing::info!(
|
||||
session_id = session_id.as_ref(),
|
||||
"server doesn't support delete session"
|
||||
|
|
@ -338,7 +345,7 @@ impl<C: StreamableHttpClient> Worker for StreamableHttpClientWorker<C> {
|
|||
.map_err(WorkerQuitReason::fatal_context(
|
||||
"send initialized notification",
|
||||
))?
|
||||
.expect_accepted::<Self::Error>()
|
||||
.expect_accepted::<C::Error>()
|
||||
.map_err(WorkerQuitReason::fatal_context(
|
||||
"process initialized notification response",
|
||||
))?;
|
||||
|
|
@ -373,14 +380,14 @@ impl<C: StreamableHttpClient> Worker for StreamableHttpClientWorker<C> {
|
|||
));
|
||||
tracing::debug!("got common stream");
|
||||
}
|
||||
Err(StreamableHttpError::SeverDoesNotSupportSse) => {
|
||||
Err(StreamableHttpError::ServerDoesNotSupportSse) => {
|
||||
tracing::debug!("server doesn't support sse, skip common stream");
|
||||
}
|
||||
Err(e) => {
|
||||
// fail to get common stream
|
||||
tracing::error!("fail to get common stream: {e}");
|
||||
return Err(WorkerQuitReason::fatal(
|
||||
"fail to get general purpose event stream",
|
||||
e,
|
||||
"get general purpose event stream",
|
||||
));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue