1use serde_json::{to_value, Value};
2use std::fmt;
3use unc_primitives::errors::TxExecutionError;
4
5#[derive(Debug, serde::Serialize)]
6pub struct RpcParseError(pub String);
7
8#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq)]
12#[serde(deny_unknown_fields)]
13pub struct RpcError {
14 #[serde(flatten)]
15 pub error_struct: Option<RpcErrorKind>,
16 pub code: i64,
18 pub message: String,
20 #[serde(skip_serializing_if = "Option::is_none")]
22 pub data: Option<Value>,
23}
24
25#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq)]
26#[serde(tag = "name", content = "cause", rename_all = "SCREAMING_SNAKE_CASE")]
27pub enum RpcErrorKind {
28 RequestValidationError(RpcRequestValidationErrorKind),
29 HandlerError(Value),
30 InternalError(Value),
31}
32
33#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq)]
34#[serde(tag = "name", content = "info", rename_all = "SCREAMING_SNAKE_CASE")]
35pub enum RpcRequestValidationErrorKind {
36 MethodNotFound { method_name: String },
37 ParseError { error_message: String },
38}
39
40#[derive(
42 serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone, unc_rpc_error_macro::RpcError,
43)]
44pub enum ServerError {
45 TxExecutionError(TxExecutionError),
46 Timeout,
47 Closed,
48}
49
50impl RpcError {
51 pub fn new(code: i64, message: String, data: Option<Value>) -> Self {
55 RpcError { code, message, data, error_struct: None }
56 }
57
58 #[cfg(feature = "test_features")]
60 pub fn invalid_params(data: impl serde::Serialize) -> Self {
61 let value = match to_value(data) {
62 Ok(value) => value,
63 Err(err) => {
64 return Self::server_error(Some(format!(
65 "Failed to serialize invalid parameters error: {:?}",
66 err.to_string()
67 )))
68 }
69 };
70 RpcError::new(-32_602, "Invalid params".to_owned(), Some(value))
71 }
72
73 #[cfg(feature = "test_features")]
75 pub fn server_error<E: serde::Serialize>(e: Option<E>) -> Self {
76 RpcError::new(
77 -32_000,
78 "Server error".to_owned(),
79 e.map(|v| to_value(v).expect("Must be representable in JSON")),
80 )
81 }
82
83 pub fn parse_error(e: String) -> Self {
85 RpcError {
86 code: -32_700,
87 message: "Parse error".to_owned(),
88 data: Some(Value::String(e.clone())),
89 error_struct: Some(RpcErrorKind::RequestValidationError(
90 RpcRequestValidationErrorKind::ParseError { error_message: e },
91 )),
92 }
93 }
94
95 pub fn serialization_error(e: String) -> Self {
96 RpcError::new_internal_error(Some(Value::String(e.clone())), e)
97 }
98
99 pub fn new_internal_or_handler_error(error_data: Option<Value>, error_struct: Value) -> Self {
102 if error_struct["name"] == "INTERNAL_ERROR" {
103 let error_message = match error_struct["info"].get("error_message") {
104 Some(Value::String(error_message)) => error_message.as_str(),
105 _ => "InternalError happened during serializing InternalError",
106 };
107 Self::new_internal_error(error_data, error_message.to_string())
108 } else {
109 Self::new_handler_error(error_data, error_struct)
110 }
111 }
112
113 pub fn new_internal_error(error_data: Option<Value>, info: String) -> Self {
114 RpcError {
115 code: -32_000,
116 message: "Server error".to_owned(),
117 data: error_data,
118 error_struct: Some(RpcErrorKind::InternalError(serde_json::json!({
119 "name": "INTERNAL_ERROR",
120 "info": serde_json::json!({"error_message": info})
121 }))),
122 }
123 }
124
125 fn new_handler_error(error_data: Option<Value>, error_struct: Value) -> Self {
126 RpcError {
127 code: -32_000,
128 message: "Server error".to_owned(),
129 data: error_data,
130 error_struct: Some(RpcErrorKind::HandlerError(error_struct)),
131 }
132 }
133
134 pub fn method_not_found(method: String) -> Self {
136 RpcError {
137 code: -32_601,
138 message: "Method not found".to_owned(),
139 data: Some(Value::String(method.clone())),
140 error_struct: Some(RpcErrorKind::RequestValidationError(
141 RpcRequestValidationErrorKind::MethodNotFound { method_name: method },
142 )),
143 }
144 }
145}
146
147impl fmt::Display for RpcError {
148 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149 write!(f, "{:?}", self)
150 }
151}
152
153impl From<RpcParseError> for RpcError {
154 fn from(parse_error: RpcParseError) -> Self {
155 Self::parse_error(parse_error.0)
156 }
157}
158
159impl From<std::convert::Infallible> for RpcError {
160 fn from(_: std::convert::Infallible) -> Self {
161 unsafe { core::hint::unreachable_unchecked() }
162 }
163}
164
165impl fmt::Display for ServerError {
166 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167 match self {
168 ServerError::TxExecutionError(e) => write!(f, "ServerError: {}", e),
169 ServerError::Timeout => write!(f, "ServerError: Timeout"),
170 ServerError::Closed => write!(f, "ServerError: Closed"),
171 }
172 }
173}
174
175impl From<ServerError> for RpcError {
176 fn from(e: ServerError) -> RpcError {
177 let error_data = match to_value(&e) {
178 Ok(value) => value,
179 Err(_err) => {
180 return RpcError::new_internal_error(
181 None,
182 "Failed to serialize ServerError".to_string(),
183 )
184 }
185 };
186 match e {
187 ServerError::TxExecutionError(_) => {
188 RpcError::new_handler_error(Some(error_data.clone()), error_data)
189 }
190 _ => RpcError::new_internal_error(Some(error_data), e.to_string()),
191 }
192 }
193}