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