starknet_devnet_server/rpc_core/
error.rs1use std::borrow::Cow;
3use std::fmt;
4
5use serde::{Deserialize, Deserializer, Serialize, Serializer};
6use serde_json::json;
7
8#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
10#[serde(deny_unknown_fields)]
11pub struct RpcError {
12 pub code: ErrorCode,
13 pub message: Cow<'static, str>,
15 #[serde(skip_serializing_if = "Option::is_none")]
16 pub data: Option<serde_json::Value>,
17}
18
19impl RpcError {
20 pub const fn new(code: ErrorCode) -> Self {
22 RpcError { message: Cow::Borrowed(code.message()), code, data: None }
23 }
24
25 pub fn parse_error<R>(reason: R) -> Self
27 where
28 R: Into<String>,
29 {
30 RpcError {
31 code: ErrorCode::ParseError,
32 message: Cow::Borrowed(ErrorCode::ParseError.message()),
33 data: Some(json!({ "reason": reason.into() })),
34 }
35 }
36 pub const fn method_not_found() -> Self {
38 Self::new(ErrorCode::MethodNotFound)
39 }
40
41 pub const fn invalid_request() -> Self {
43 Self::new(ErrorCode::InvalidRequest)
44 }
45
46 pub fn invalid_request_with_reason<R>(reason: R) -> Self
48 where
49 R: Into<String>,
50 {
51 RpcError {
52 code: ErrorCode::InvalidRequest,
53 message: Cow::Borrowed(ErrorCode::InvalidRequest.message()),
54 data: Some(json!({ "reason": reason.into() })),
55 }
56 }
57
58 pub const fn internal_error() -> Self {
60 Self::new(ErrorCode::InternalError)
61 }
62
63 pub fn invalid_params<M>(message: M) -> Self
65 where
66 M: Into<String>,
67 {
68 RpcError { code: ErrorCode::InvalidParams, message: message.into().into(), data: None }
69 }
70
71 pub fn internal_error_with<M>(message: M) -> Self
73 where
74 M: Into<String>,
75 {
76 RpcError { code: ErrorCode::InternalError, message: message.into().into(), data: None }
77 }
78
79 pub fn transaction_rejected<M>(message: M) -> Self
81 where
82 M: Into<String>,
83 {
84 RpcError {
85 code: ErrorCode::TransactionRejected,
86 message: message.into().into(),
87 data: None,
88 }
89 }
90}
91
92impl fmt::Display for RpcError {
93 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94 write!(f, "{}: {}", self.code.message(), self.message)
95 }
96}
97
98#[derive(Clone, Copy, Debug, PartialEq, Eq)]
100pub enum ErrorCode {
101 ParseError,
104 InvalidRequest,
106 MethodNotFound,
108 InvalidParams,
110 InternalError,
112 TransactionRejected,
114 ExecutionError,
116 MethodForbidden,
118 ServerError(i64),
120}
121
122impl ErrorCode {
123 pub fn code(&self) -> i64 {
125 match *self {
126 ErrorCode::ParseError => -32700,
127 ErrorCode::InvalidRequest => -32600,
128 ErrorCode::MethodNotFound => -32601,
129 ErrorCode::InvalidParams => -32602,
130 ErrorCode::InternalError => -32603,
131 ErrorCode::MethodForbidden => -32604,
132 ErrorCode::TransactionRejected => -32003,
133 ErrorCode::ExecutionError => 3,
134 ErrorCode::ServerError(c) => c,
135 }
136 }
137
138 pub const fn message(&self) -> &'static str {
140 match *self {
141 ErrorCode::ParseError => "Parse error",
142 ErrorCode::InvalidRequest => "Invalid request",
143 ErrorCode::MethodNotFound => "Method not found",
144 ErrorCode::InvalidParams => "Invalid params",
145 ErrorCode::InternalError => "Internal error",
146 ErrorCode::TransactionRejected => "Transaction rejected",
147 ErrorCode::ServerError(_) => "Server error",
148 ErrorCode::ExecutionError => "Execution error",
149 ErrorCode::MethodForbidden => "Method forbidden",
150 }
151 }
152}
153
154impl Serialize for ErrorCode {
155 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
156 where
157 S: Serializer,
158 {
159 serializer.serialize_i64(self.code())
160 }
161}
162
163impl<'a> Deserialize<'a> for ErrorCode {
164 fn deserialize<D>(deserializer: D) -> Result<ErrorCode, D::Error>
165 where
166 D: Deserializer<'a>,
167 {
168 i64::deserialize(deserializer).map(Into::into)
169 }
170}
171
172impl From<i64> for ErrorCode {
173 fn from(code: i64) -> Self {
174 match code {
175 -32700 => ErrorCode::ParseError,
176 -32600 => ErrorCode::InvalidRequest,
177 -32601 => ErrorCode::MethodNotFound,
178 -32602 => ErrorCode::InvalidParams,
179 -32603 => ErrorCode::InternalError,
180 -32604 => ErrorCode::MethodForbidden,
181 -32003 => ErrorCode::TransactionRejected,
182 3 => ErrorCode::ExecutionError,
183 _ => ErrorCode::ServerError(code),
184 }
185 }
186}