turul_mcp_json_rpc_server/
error.rs1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::fmt;
4use thiserror::Error;
5
6use crate::types::RequestId;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum JsonRpcErrorCode {
11 ParseError,
12 InvalidRequest,
13 MethodNotFound,
14 InvalidParams,
15 InternalError,
16 ServerError(i64), }
18
19impl JsonRpcErrorCode {
20 pub fn code(&self) -> i64 {
21 match self {
22 JsonRpcErrorCode::ParseError => -32700,
23 JsonRpcErrorCode::InvalidRequest => -32600,
24 JsonRpcErrorCode::MethodNotFound => -32601,
25 JsonRpcErrorCode::InvalidParams => -32602,
26 JsonRpcErrorCode::InternalError => -32603,
27 JsonRpcErrorCode::ServerError(code) => *code,
28 }
29 }
30
31 pub fn message(&self) -> &'static str {
32 match self {
33 JsonRpcErrorCode::ParseError => "Parse error",
34 JsonRpcErrorCode::InvalidRequest => "Invalid Request",
35 JsonRpcErrorCode::MethodNotFound => "Method not found",
36 JsonRpcErrorCode::InvalidParams => "Invalid params",
37 JsonRpcErrorCode::InternalError => "Internal error",
38 JsonRpcErrorCode::ServerError(_) => "Server error",
39 }
40 }
41}
42
43impl fmt::Display for JsonRpcErrorCode {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 write!(f, "{}: {}", self.code(), self.message())
46 }
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct JsonRpcErrorObject {
52 pub code: i64,
53 pub message: String,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub data: Option<Value>,
56}
57
58impl JsonRpcErrorObject {
59 pub fn new(code: JsonRpcErrorCode, message: Option<String>, data: Option<Value>) -> Self {
60 Self {
61 code: code.code(),
62 message: message.unwrap_or_else(|| code.message().to_string()),
63 data,
64 }
65 }
66
67 pub fn parse_error(data: Option<Value>) -> Self {
68 Self::new(JsonRpcErrorCode::ParseError, None, data)
69 }
70
71 pub fn invalid_request(data: Option<Value>) -> Self {
72 Self::new(JsonRpcErrorCode::InvalidRequest, None, data)
73 }
74
75 pub fn method_not_found(method: &str) -> Self {
76 Self::new(
77 JsonRpcErrorCode::MethodNotFound,
78 Some(format!("Method '{}' not found", method)),
79 None,
80 )
81 }
82
83 pub fn invalid_params(message: &str) -> Self {
84 Self::new(
85 JsonRpcErrorCode::InvalidParams,
86 Some(message.to_string()),
87 None,
88 )
89 }
90
91 pub fn internal_error(message: Option<String>) -> Self {
92 Self::new(JsonRpcErrorCode::InternalError, message, None)
93 }
94
95 pub fn server_error(code: i64, message: &str, data: Option<Value>) -> Self {
96 assert!((-32099..=-32000).contains(&code), "Server error code must be in range -32099 to -32000");
97 Self::new(
98 JsonRpcErrorCode::ServerError(code),
99 Some(message.to_string()),
100 data,
101 )
102 }
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct JsonRpcError {
108 #[serde(rename = "jsonrpc")]
109 pub version: String,
110 pub id: Option<RequestId>,
111 pub error: JsonRpcErrorObject,
112}
113
114impl JsonRpcError {
115 pub fn new(id: Option<RequestId>, error: JsonRpcErrorObject) -> Self {
116 Self {
117 version: crate::JSONRPC_VERSION.to_string(),
118 id,
119 error,
120 }
121 }
122
123 pub fn parse_error() -> Self {
124 Self::new(None, JsonRpcErrorObject::parse_error(None))
125 }
126
127 pub fn invalid_request(id: Option<RequestId>) -> Self {
128 Self::new(id, JsonRpcErrorObject::invalid_request(None))
129 }
130
131 pub fn method_not_found(id: RequestId, method: &str) -> Self {
132 Self::new(Some(id), JsonRpcErrorObject::method_not_found(method))
133 }
134
135 pub fn invalid_params(id: RequestId, message: &str) -> Self {
136 Self::new(Some(id), JsonRpcErrorObject::invalid_params(message))
137 }
138
139 pub fn internal_error(id: Option<RequestId>, message: Option<String>) -> Self {
140 Self::new(id, JsonRpcErrorObject::internal_error(message))
141 }
142}
143
144impl fmt::Display for JsonRpcError {
145 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
146 write!(f, "JSON-RPC Error {}: {}", self.error.code, self.error.message)
147 }
148}
149
150impl std::error::Error for JsonRpcError {}
151
152#[derive(Debug, Error)]
154pub enum JsonRpcProcessingError {
155 #[error("JSON parse error: {0}")]
156 JsonParseError(#[from] serde_json::Error),
157
158 #[error("JSON-RPC error: {0}")]
159 RpcError(#[from] JsonRpcError),
160
161 #[error("Method handler error: {0}")]
162 HandlerError(String),
163
164 #[error("Internal error: {0}")]
165 InternalError(String),
166}
167
168impl JsonRpcProcessingError {
169 pub fn to_rpc_error(&self, id: Option<RequestId>) -> JsonRpcError {
170 match self {
171 JsonRpcProcessingError::JsonParseError(_) => JsonRpcError::parse_error(),
172 JsonRpcProcessingError::RpcError(err) => err.clone(),
173 JsonRpcProcessingError::HandlerError(msg) => {
174 JsonRpcError::internal_error(id, Some(msg.clone()))
175 }
176 JsonRpcProcessingError::InternalError(msg) => {
177 JsonRpcError::internal_error(id, Some(msg.clone()))
178 }
179 }
180 }
181}
182
183#[cfg(test)]
184mod tests {
185 use super::*;
186
187 #[test]
188 fn test_error_codes() {
189 assert_eq!(JsonRpcErrorCode::ParseError.code(), -32700);
190 assert_eq!(JsonRpcErrorCode::MethodNotFound.code(), -32601);
191 }
192
193 #[test]
194 fn test_error_serialization() {
195 let error = JsonRpcError::method_not_found(RequestId::Number(1), "test");
196 let json = serde_json::to_string(&error).unwrap();
197 assert!(json.contains("Method 'test' not found"));
198 }
199}