Skip to content

Commit 1197b0c

Browse files
committed
Add handling for jsonrpc error responses
1 parent b3af3de commit 1197b0c

File tree

3 files changed

+44
-15
lines changed

3 files changed

+44
-15
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ethportal-peertest/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ log = "0.4.14"
1212
rocksdb = "0.16.0"
1313
serde_json = "1.0.59"
1414
structopt = "0.3"
15+
thiserror = "1.0.29"
1516
tokio = {version = "1.8.0", features = ["full"]}
1617
tracing = "0.1.26"
1718
tracing-subscriber = "0.2.18"

ethportal-peertest/src/jsonrpc.rs

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::slice::Iter;
55
use hyper::{self, Body, Client, Method, Request};
66
use log::info;
77
use serde_json::{self, Value};
8+
use thiserror::Error;
89

910
use trin_core::portalnet::U256;
1011

@@ -78,44 +79,65 @@ impl JsonRpcEndpoint {
7879
ALL_ENDPOINTS.iter()
7980
}
8081

81-
pub fn to_jsonrpc(self) -> Vec<u8> {
82-
let data = format!(
82+
pub fn to_jsonrpc(self) -> String {
83+
format!(
8384
r#"
8485
{{
8586
"jsonrpc":"2.0",
8687
"id": {},
8788
"method": "{}"
8889
}}"#,
8990
self.id, self.method
90-
);
91-
let v: Value = serde_json::from_str(&data).unwrap();
92-
serde_json::to_vec(&v).unwrap()
91+
)
9392
}
9493
}
9594

9695
pub async fn test_jsonrpc_endpoints_over_ipc() {
9796
for endpoint in JsonRpcEndpoint::all_endpoints() {
9897
info!("Testing over IPC: {:?}", endpoint.method);
9998
let mut stream = UnixStream::connect("/tmp/trin-jsonrpc.ipc").unwrap();
100-
stream.write_all(&endpoint.to_jsonrpc()).unwrap();
99+
let v: Value = serde_json::from_str(&endpoint.to_jsonrpc()).unwrap();
100+
let data = serde_json::to_vec(&v).unwrap();
101+
stream.write_all(&data).unwrap();
101102
stream.flush().unwrap();
102103
let deser = serde_json::Deserializer::from_reader(stream);
103104
for obj in deser.into_iter::<Value>() {
104105
let response_obj = obj.unwrap();
105-
let result = response_obj.get("result").unwrap();
106-
validate_endpoint_response(endpoint.method, result);
106+
match get_response_result(response_obj) {
107+
Ok(result) => validate_endpoint_response(endpoint.method, &result),
108+
Err(msg) => panic!(
109+
"Jsonrpc error for {:?} endpoint: {:?}",
110+
endpoint.method, msg
111+
),
112+
}
107113
}
108114
}
109115
}
110116

117+
#[derive(Error, Debug)]
118+
pub enum JsonRpcResponseError {
119+
#[error("JsonRpc response contains an error: {0}")]
120+
Error(String),
121+
122+
#[error("Invalid JsonRpc response")]
123+
Invalid(),
124+
}
125+
126+
fn get_response_result(response: Value) -> Result<Value, JsonRpcResponseError> {
127+
match response.get("result") {
128+
Some(result) => Ok(result.clone()),
129+
None => match response.get("error") {
130+
Some(error) => Err(JsonRpcResponseError::Error(error.to_string())),
131+
None => Err(JsonRpcResponseError::Invalid()),
132+
},
133+
}
134+
}
135+
111136
pub async fn test_jsonrpc_endpoints_over_http() {
112137
let client = Client::new();
113138
for endpoint in JsonRpcEndpoint::all_endpoints() {
114139
info!("Testing over HTTP: {:?}", endpoint.method);
115-
let json_string = format!(
116-
r#"{{"jsonrpc":"2.0","id":0,"method":"{}","params":[]}}"#,
117-
endpoint.method
118-
);
140+
let json_string = endpoint.to_jsonrpc();
119141
let req = Request::builder()
120142
.method(Method::POST)
121143
.uri("http://127.0.0.1:8545")
@@ -124,8 +146,13 @@ pub async fn test_jsonrpc_endpoints_over_http() {
124146
.unwrap();
125147
let resp = client.request(req).await.unwrap();
126148
let body = hyper::body::to_bytes(resp.into_body()).await.unwrap();
127-
let body_json: Value = serde_json::from_slice(&body).unwrap();
128-
let result = body_json.get("result").unwrap();
129-
validate_endpoint_response(endpoint.method, result);
149+
let response_obj: Value = serde_json::from_slice(&body).unwrap();
150+
match get_response_result(response_obj) {
151+
Ok(result) => validate_endpoint_response(endpoint.method, &result),
152+
Err(msg) => panic!(
153+
"Jsonrpc error for {:?} endpoint: {:?}",
154+
endpoint.method, msg
155+
),
156+
}
130157
}
131158
}

0 commit comments

Comments
 (0)