Skip to content

Commit a7af24b

Browse files
Surface bitcoind rpc error code
Users of the RpcClient had no way to access the error code returned by bitcoind's rpc. We embed a new RpcError struct as the inner error for the returned io::Error. Users can access both the code and the message using this inner struct.
1 parent 8311581 commit a7af24b

File tree

1 file changed

+27
-3
lines changed
  • lightning-block-sync/src

1 file changed

+27
-3
lines changed

lightning-block-sync/src/rpc.rs

+27-3
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,27 @@ use serde_json;
1313

1414
use std::convert::TryFrom;
1515
use std::convert::TryInto;
16+
use std::error::Error;
17+
use std::fmt;
1618
use std::sync::atomic::{AtomicUsize, Ordering};
1719

20+
/// An error returned by the RPC server.
21+
#[derive(Debug)]
22+
pub struct RpcError {
23+
/// The error code.
24+
pub code: i64,
25+
/// The error message.
26+
pub message: String,
27+
}
28+
29+
impl fmt::Display for RpcError {
30+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31+
write!(f, "RPC error {}: {}", self.code, self.message)
32+
}
33+
}
34+
35+
impl Error for RpcError {}
36+
1837
/// A simple RPC client for calling methods using HTTP `POST`.
1938
pub struct RpcClient {
2039
basic_auth: String,
@@ -69,8 +88,11 @@ impl RpcClient {
6988
let error = &response["error"];
7089
if !error.is_null() {
7190
// TODO: Examine error code for a more precise std::io::ErrorKind.
72-
let message = error["message"].as_str().unwrap_or("unknown error");
73-
return Err(std::io::Error::new(std::io::ErrorKind::Other, message));
91+
let rpc_error = RpcError {
92+
code: error["code"].as_i64().unwrap_or(-1),
93+
message: error["message"].as_str().unwrap_or("unknown error").to_string()
94+
};
95+
return Err(std::io::Error::new(std::io::ErrorKind::Other, rpc_error));
7496
}
7597

7698
let result = &mut response["result"];
@@ -163,7 +185,9 @@ mod tests {
163185
match client.call_method::<u64>("getblock", &[invalid_block_hash]).await {
164186
Err(e) => {
165187
assert_eq!(e.kind(), std::io::ErrorKind::Other);
166-
assert_eq!(e.get_ref().unwrap().to_string(), "invalid parameter");
188+
let rpc_error: Box<RpcError> = e.into_inner().unwrap().downcast().unwrap();
189+
assert_eq!(rpc_error.code, -8);
190+
assert_eq!(rpc_error.message, "invalid parameter");
167191
},
168192
Ok(_) => panic!("Expected error"),
169193
}

0 commit comments

Comments
 (0)