mcpkit_core/error/
jsonrpc.rs1use serde::{Deserialize, Serialize};
7
8use super::types::McpError;
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct JsonRpcError {
13 pub code: i32,
15 pub message: String,
17 #[serde(skip_serializing_if = "Option::is_none")]
19 pub data: Option<serde_json::Value>,
20}
21
22impl JsonRpcError {
23 pub fn invalid_params(message: impl Into<String>) -> Self {
25 Self {
26 code: -32602,
27 message: message.into(),
28 data: None,
29 }
30 }
31
32 pub fn internal_error(message: impl Into<String>) -> Self {
34 Self {
35 code: -32603,
36 message: message.into(),
37 data: None,
38 }
39 }
40
41 pub fn method_not_found(message: impl Into<String>) -> Self {
43 Self {
44 code: -32601,
45 message: message.into(),
46 data: None,
47 }
48 }
49
50 pub fn parse_error(message: impl Into<String>) -> Self {
52 Self {
53 code: -32700,
54 message: message.into(),
55 data: None,
56 }
57 }
58
59 pub fn invalid_request(message: impl Into<String>) -> Self {
61 Self {
62 code: -32600,
63 message: message.into(),
64 data: None,
65 }
66 }
67}
68
69impl From<&McpError> for JsonRpcError {
70 fn from(err: &McpError) -> Self {
71 let code = err.code();
72 let message = err.to_string();
73 let data = match err {
74 McpError::MethodNotFound {
75 method, available, ..
76 } => Some(serde_json::json!({
77 "method": method,
78 "available": available,
79 })),
80 McpError::InvalidParams(details) => Some(serde_json::json!({
81 "method": details.method,
82 "param_path": details.param_path,
83 "expected": details.expected,
84 "actual": details.actual,
85 })),
86 McpError::Transport(details) => Some(serde_json::json!({
87 "kind": format!("{:?}", details.kind),
88 "context": details.context,
89 })),
90 McpError::ToolExecution(details) => details
91 .data
92 .clone()
93 .or_else(|| Some(serde_json::json!({ "tool": details.tool }))),
94 McpError::HandshakeFailed(details) => Some(serde_json::json!({
95 "client_version": details.client_version,
96 "server_version": details.server_version,
97 })),
98 McpError::WithContext { source, .. } => {
99 let inner: Self = source.as_ref().into();
100 inner.data
101 }
102 _ => None,
103 };
104
105 Self {
106 code,
107 message,
108 data,
109 }
110 }
111}
112
113impl From<McpError> for JsonRpcError {
114 fn from(err: McpError) -> Self {
115 Self::from(&err)
116 }
117}