Skip to main content

greentic_mcp_client/
error.rs

1//! Error types shared by the sans-io proto layer and the native client.
2
3use thiserror::Error;
4
5/// Failure decoding a JSON-RPC envelope from an HTTP body.
6#[derive(Debug, Error)]
7pub enum ProtoError {
8    #[error("response body is not UTF-8: {0}")]
9    NotUtf8(#[from] std::str::Utf8Error),
10    #[error("decode JSON-RPC response: {0}")]
11    Decode(#[from] serde_json::Error),
12    #[error("no JSON-RPC response found in SSE stream")]
13    NoEnvelope,
14    #[error("JSON-RPC response has neither result nor error")]
15    MissingResult,
16}
17
18/// A JSON-RPC `error` object returned by the server.
19#[derive(Debug, Error, PartialEq, Eq)]
20#[error("JSON-RPC error {code}: {message}")]
21pub struct ServerError {
22    pub code: i64,
23    pub message: String,
24}
25
26/// A `tools/call` result carrying `isError: true`. The message is the
27/// server-provided error payload (structured content stringified, or the
28/// joined text blocks).
29#[derive(Debug, Error, PartialEq, Eq)]
30#[error("{message}")]
31pub struct ToolCallError {
32    pub message: String,
33}
34
35/// Unified error surface for the native client. The sans-io layer returns the
36/// narrower types above; `McpError` wraps them via `From` so `?` flows.
37#[derive(Debug, Error)]
38pub enum McpError {
39    #[cfg(feature = "native")]
40    #[error("transport: {0}")]
41    Transport(#[from] reqwest::Error),
42    /// Failed to launch a stdio MCP server subprocess (e.g. command not found).
43    #[cfg(feature = "native")]
44    #[error("failed to spawn stdio MCP server `{command}`: {source}")]
45    Spawn {
46        command: String,
47        source: std::io::Error,
48    },
49    /// A stdio transport fault: a broken pipe, a read timeout, or the child
50    /// exiting before answering a request.
51    #[cfg(feature = "native")]
52    #[error("stdio transport: {0}")]
53    StdioTransport(String),
54    #[error("protocol: {0}")]
55    Proto(#[from] ProtoError),
56    #[error(transparent)]
57    Server(#[from] ServerError),
58    #[error("tool call failed: {0}")]
59    ToolCall(#[from] ToolCallError),
60    #[error("initialize result malformed: {0}")]
61    BadInitialize(String),
62}