Skip to main content

mcp_utils/client/
error.rs

1use aether_auth::OAuthError;
2use rmcp::service::{ClientInitializeError, ServiceError};
3use rmcp::transport::auth::AuthError;
4use std::io;
5use std::path::PathBuf;
6use std::time::Duration;
7use thiserror::Error;
8
9#[derive(Debug, Error)]
10pub enum ClientError {
11    #[error("Failed to spawn '{command}': {source}")]
12    Spawn {
13        command: String,
14        #[source]
15        source: io::Error,
16    },
17    #[error("Failed to connect to MCP socket {}: {source}", path.display())]
18    SocketConnect {
19        path: PathBuf,
20        #[source]
21        source: io::Error,
22    },
23    #[error("Failed to connect to MCP server '{server}': {source}")]
24    Connect {
25        server: String,
26        #[source]
27        source: Box<ClientInitializeError>,
28    },
29    #[error("MCP server '{server}' requires OAuth authorization")]
30    AuthRequired { server: String, challenge: Option<String> },
31    #[error("MCP server '{server}' cannot be authorized interactively")]
32    OAuthUnavailable { server: String },
33    #[error("OAuth failed for MCP server '{server}': {source}")]
34    Auth {
35        server: String,
36        #[source]
37        source: OAuthError,
38    },
39    #[error("OAuth {step} failed for MCP server '{server}': {source}")]
40    AuthFlow {
41        server: String,
42        step: &'static str,
43        #[source]
44        source: AuthError,
45    },
46    #[error("Authentication for MCP server '{server}' timed out after {timeout:?}")]
47    AuthTimedOut { server: String, timeout: Duration },
48    #[error("Request to MCP server '{server}' failed: {source}")]
49    Request {
50        server: String,
51        #[source]
52        source: Box<ServiceError>,
53    },
54    #[error("MCP server '{server}' disconnected")]
55    Disconnected { server: String },
56}
57
58impl ClientError {
59    pub(crate) fn connect(server: impl Into<String>, source: ClientInitializeError) -> Self {
60        Self::Connect { server: server.into(), source: Box::new(source) }
61    }
62
63    pub(crate) fn request(server: impl Into<String>, source: ServiceError) -> Self {
64        Self::Request { server: server.into(), source: Box::new(source) }
65    }
66}
67
68pub(crate) type Result<T> = std::result::Result<T, ClientError>;