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