near_jsonrpc_primitives/
errors.rs

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/// This struct may be returned from JSON RPC server in case of error
10/// It is expected that this struct has impl From<_> all other RPC errors
11/// like [RpcBlockError](crate::types::blocks::RpcBlockError)
12#[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    /// Deprecated please use the `error_struct` instead
19    pub code: i64,
20    /// Deprecated please use the `error_struct` instead
21    pub message: String,
22    /// Deprecated please use the `error_struct` instead
23    #[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/// A general Server Error
45#[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    /// A generic constructor.
54    ///
55    /// Mostly for completeness, doesn't do anything but filling in the corresponding fields.
56    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    /// Create an Invalid Param error.
62    #[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    /// Create a server error.
77    #[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    /// Create a parse error.
87    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    /// Helper method to define extract INTERNAL_ERROR in separate RpcErrorKind
103    /// Returns HANDLER_ERROR if the error is not internal one
104    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    /// Create a method not found error.
138    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}