@@ -13,8 +13,27 @@ use serde_json;
1313
1414use std:: convert:: TryFrom ;
1515use std:: convert:: TryInto ;
16+ use std:: error:: Error ;
17+ use std:: fmt;
1618use 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`.
1938pub 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