1use serde_json::Value;
2use thiserror::Error;
3
4#[derive(Debug, Clone, Copy)]
5pub enum ErrorCode {
6 ParseError,
7 InvalidRequest,
8 MethodNotFound,
9 InvalidParams,
10 InternalError,
11 ServerError,
12}
13
14impl ErrorCode {
15 pub fn code(self) -> i64 {
16 match self {
17 Self::ParseError => -32700,
18 Self::InvalidRequest => -32600,
19 Self::MethodNotFound => -32601,
20 Self::InvalidParams => -32602,
21 Self::InternalError => -32603,
22 Self::ServerError => -32000,
23 }
24 }
25}
26
27impl std::fmt::Display for ErrorCode {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 write!(f, "{}", self.code())
30 }
31}
32
33#[derive(Debug, Error)]
34pub enum Error {
35 #[error("io error: {0}")]
36 Io(#[from] std::io::Error),
37 #[error("json error: {0}")]
38 Json(#[from] serde_json::Error),
39 #[error("rpc error {code}: {message}")]
40 Rpc {
41 code: ErrorCode,
42 message: String,
43 data: Option<Value>,
44 },
45 #[error("protocol error: {0}")]
46 Protocol(&'static str),
47}
48
49impl Error {
50 pub fn method_not_found(method: &str) -> Self {
51 Self::Rpc {
52 code: ErrorCode::MethodNotFound,
53 message: format!("method not found: {method}"),
54 data: None,
55 }
56 }
57
58 pub fn invalid_params(message: impl Into<String>) -> Self {
59 Self::Rpc {
60 code: ErrorCode::InvalidParams,
61 message: message.into(),
62 data: None,
63 }
64 }
65
66 pub fn is_method_not_found(&self) -> bool {
67 matches!(
68 self,
69 Error::Rpc {
70 code: ErrorCode::MethodNotFound,
71 ..
72 }
73 )
74 }
75}
76
77#[cfg(test)]
78mod test;