1use std::{error, fmt};
8
9use serde::{Deserialize, Serialize};
10
11use crate::Response;
12
13#[derive(Debug)]
15#[non_exhaustive]
16pub enum Error {
17 Transport(Box<dyn error::Error + Send + Sync>),
19 Json(serde_json::Error),
21 Rpc(RpcError),
23 NonceMismatch,
25 VersionMismatch,
27 EmptyBatch,
29 WrongBatchResponseSize,
31 BatchDuplicateResponseId(serde_json::Value),
33 WrongBatchResponseId(serde_json::Value),
35}
36
37impl From<serde_json::Error> for Error {
38 fn from(e: serde_json::Error) -> Error {
39 Error::Json(e)
40 }
41}
42
43impl From<RpcError> for Error {
44 fn from(e: RpcError) -> Error {
45 Error::Rpc(e)
46 }
47}
48
49impl fmt::Display for Error {
50 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51 use Error::*;
52
53 match *self {
54 Transport(ref e) => write!(f, "transport error: {}", e),
55 Json(ref e) => write!(f, "JSON decode error: {}", e),
56 Rpc(ref r) => write!(f, "RPC error response: {:?}", r),
57 BatchDuplicateResponseId(ref v) => write!(f, "duplicate RPC batch response ID: {}", v),
58 WrongBatchResponseId(ref v) => write!(f, "wrong RPC batch response ID: {}", v),
59 NonceMismatch => write!(f, "nonce of response did not match nonce of request"),
60 VersionMismatch => write!(f, "`jsonrpc` field set to non-\"2.0\""),
61 EmptyBatch => write!(f, "batches can't be empty"),
62 WrongBatchResponseSize => write!(f, "too many responses returned in batch"),
63 }
64 }
65}
66
67impl error::Error for Error {
68 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
69 use self::Error::*;
70
71 match *self {
72 Rpc(_)
73 | NonceMismatch
74 | VersionMismatch
75 | EmptyBatch
76 | WrongBatchResponseSize
77 | BatchDuplicateResponseId(_)
78 | WrongBatchResponseId(_) => None,
79 Transport(ref e) => Some(&**e),
80 Json(ref e) => Some(e),
81 }
82 }
83}
84
85#[derive(Debug)]
108pub enum StandardError {
109 ParseError,
112 InvalidRequest,
114 MethodNotFound,
116 InvalidParams,
118 InternalError,
120}
121
122#[derive(Clone, Debug, Deserialize, Serialize)]
124pub struct RpcError {
125 pub code: i32,
127 pub message: String,
129 pub data: Option<Box<serde_json::value::RawValue>>,
131}
132
133pub fn standard_error(
135 code: StandardError,
136 data: Option<Box<serde_json::value::RawValue>>,
137) -> RpcError {
138 match code {
139 StandardError::ParseError => RpcError {
140 code: -32700,
141 message: "Parse error".to_string(),
142 data,
143 },
144 StandardError::InvalidRequest => RpcError {
145 code: -32600,
146 message: "Invalid Request".to_string(),
147 data,
148 },
149 StandardError::MethodNotFound => RpcError {
150 code: -32601,
151 message: "Method not found".to_string(),
152 data,
153 },
154 StandardError::InvalidParams => RpcError {
155 code: -32602,
156 message: "Invalid params".to_string(),
157 data,
158 },
159 StandardError::InternalError => RpcError {
160 code: -32603,
161 message: "Internal error".to_string(),
162 data,
163 },
164 }
165}
166
167pub fn result_to_response(
169 result: Result<serde_json::Value, RpcError>,
170 id: serde_json::Value,
171) -> Response {
172 match result {
173 Ok(data) => Response {
174 result: Some(
175 serde_json::value::RawValue::from_string(serde_json::to_string(&data).unwrap())
176 .unwrap(),
177 ),
178 error: None,
179 id,
180 jsonrpc: Some(String::from("2.0")),
181 },
182 Err(err) => Response {
183 result: None,
184 error: Some(err),
185 id,
186 jsonrpc: Some(String::from("2.0")),
187 },
188 }
189}
190
191#[cfg(test)]
192mod tests {
193 use super::StandardError::{
194 InternalError, InvalidParams, InvalidRequest, MethodNotFound, ParseError,
195 };
196 use super::{result_to_response, standard_error};
197 use serde_json;
198
199 #[test]
200 fn test_parse_error() {
201 let resp = result_to_response(Err(standard_error(ParseError, None)), From::from(1));
202 assert!(resp.result.is_none());
203 assert!(resp.error.is_some());
204 assert_eq!(resp.id, serde_json::Value::from(1));
205 assert_eq!(resp.error.unwrap().code, -32700);
206 }
207
208 #[test]
209 fn test_invalid_request() {
210 let resp = result_to_response(Err(standard_error(InvalidRequest, None)), From::from(1));
211 assert!(resp.result.is_none());
212 assert!(resp.error.is_some());
213 assert_eq!(resp.id, serde_json::Value::from(1));
214 assert_eq!(resp.error.unwrap().code, -32600);
215 }
216
217 #[test]
218 fn test_method_not_found() {
219 let resp = result_to_response(Err(standard_error(MethodNotFound, None)), From::from(1));
220 assert!(resp.result.is_none());
221 assert!(resp.error.is_some());
222 assert_eq!(resp.id, serde_json::Value::from(1));
223 assert_eq!(resp.error.unwrap().code, -32601);
224 }
225
226 #[test]
227 fn test_invalid_params() {
228 let resp = result_to_response(Err(standard_error(InvalidParams, None)), From::from("123"));
229 assert!(resp.result.is_none());
230 assert!(resp.error.is_some());
231 assert_eq!(resp.id, serde_json::Value::from("123"));
232 assert_eq!(resp.error.unwrap().code, -32602);
233 }
234
235 #[test]
236 fn test_internal_error() {
237 let resp = result_to_response(Err(standard_error(InternalError, None)), From::from(-1));
238 assert!(resp.result.is_none());
239 assert!(resp.error.is_some());
240 assert_eq!(resp.id, serde_json::Value::from(-1));
241 assert_eq!(resp.error.unwrap().code, -32603);
242 }
243}