1use std::fmt;
2use std::io;
3
4use serde_json::Value;
5use thiserror::Error;
6
7pub type Result<T, E = FastMcpError> = std::result::Result<T, E>;
9
10#[derive(Debug, Error)]
12pub enum FastMcpError {
13 #[error("tool '{0}' already registered")]
14 DuplicateTool(String),
15 #[error("tool '{0}' not found")]
16 ToolNotFound(String),
17 #[error("resource '{0}' already registered")]
18 DuplicateResource(String),
19 #[error("resource '{0}' not found")]
20 ResourceNotFound(String),
21 #[error("prompt '{0}' already registered")]
22 DuplicatePrompt(String),
23 #[error("prompt '{0}' not found")]
24 PromptNotFound(String),
25 #[error("invalid invocation payload: {0}")]
26 InvalidInvocation(String),
27 #[error("handler error: {0}")]
28 HandlerError(String),
29 #[error("serialization error: {0}")]
30 Serialization(#[from] serde_json::Error),
31 #[error("io error: {0}")]
32 Io(#[from] io::Error),
33}
34
35impl FastMcpError {
36 pub fn handler_error(err: impl fmt::Display) -> Self {
38 Self::HandlerError(err.to_string())
39 }
40}
41
42pub fn expect_object<'a>(
44 payload: &'a Value,
45 context: &'static str,
46) -> Result<&'a serde_json::Map<String, Value>> {
47 payload
48 .as_object()
49 .ok_or_else(|| FastMcpError::InvalidInvocation(format!("{context} expects a JSON object")))
50}