Implementation-defined RPC server errors are now accessible to client/ users

This commit is contained in:
Michael Vines 2020-10-12 17:47:06 -07:00
parent 7de7efe96c
commit 247228ee61
6 changed files with 29 additions and 9 deletions

View File

@ -27,6 +27,13 @@ impl HttpSender {
} }
} }
#[derive(Deserialize, Debug)]
struct RpcErrorObject {
code: i64,
message: String,
/*data field omitted*/
}
impl RpcSender for HttpSender { impl RpcSender for HttpSender {
fn send(&self, request: RpcRequest, params: serde_json::Value) -> Result<serde_json::Value> { fn send(&self, request: RpcRequest, params: serde_json::Value) -> Result<serde_json::Value> {
// Concurrent requests are not supported so reuse the same request id for all requests // Concurrent requests are not supported so reuse the same request id for all requests
@ -63,11 +70,20 @@ impl RpcSender for HttpSender {
let json: serde_json::Value = serde_json::from_str(&response.text()?)?; let json: serde_json::Value = serde_json::from_str(&response.text()?)?;
if json["error"].is_object() { if json["error"].is_object() {
return Err(RpcError::RpcRequestError(format!( return match serde_json::from_value::<RpcErrorObject>(json["error"].clone())
"RPC Error response: {}", {
serde_json::to_string(&json["error"]).unwrap() Ok(rpc_error_object) => Err(RpcError::RpcResponseError {
)) code: rpc_error_object.code,
.into()); message: rpc_error_object.message,
}
.into()),
Err(err) => Err(RpcError::RpcRequestError(format!(
"Failed to deserialize RPC error response: {} [{}]",
serde_json::to_string(&json["error"]).unwrap(),
err
))
.into()),
};
} }
return Ok(json["result"].clone()); return Ok(json["result"].clone());
} }

View File

@ -10,6 +10,7 @@ pub mod perf_utils;
pub mod pubsub_client; pub mod pubsub_client;
pub mod rpc_client; pub mod rpc_client;
pub mod rpc_config; pub mod rpc_config;
pub mod rpc_custom_error;
pub mod rpc_filter; pub mod rpc_filter;
pub mod rpc_request; pub mod rpc_request;
pub mod rpc_response; pub mod rpc_response;

View File

@ -1,5 +1,7 @@
//! Implementation defined RPC server errors
use crate::rpc_response::RpcSimulateTransactionResult;
use jsonrpc_core::{Error, ErrorCode}; use jsonrpc_core::{Error, ErrorCode};
use solana_client::rpc_response::RpcSimulateTransactionResult;
use solana_sdk::clock::Slot; use solana_sdk::clock::Slot;
const JSON_RPC_SERVER_ERROR_1: i64 = -32001; const JSON_RPC_SERVER_ERROR_1: i64 = -32001;

View File

@ -140,8 +140,10 @@ impl RpcRequest {
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum RpcError { pub enum RpcError {
#[error("rpc request error: {0}")] #[error("RPC request error: {0}")]
RpcRequestError(String), RpcRequestError(String),
#[error("RPC response error {code}: {message}")]
RpcResponseError { code: i64, message: String },
#[error("parse error: expected {0}")] #[error("parse error: expected {0}")]
ParseError(String), /* "expected" */ ParseError(String), /* "expected" */
// Anything in a `ForUser` needs to die. The caller should be // Anything in a `ForUser` needs to die. The caller should be

View File

@ -55,7 +55,6 @@ mod result;
pub mod retransmit_stage; pub mod retransmit_stage;
pub mod rewards_recorder_service; pub mod rewards_recorder_service;
pub mod rpc; pub mod rpc;
pub mod rpc_error;
pub mod rpc_health; pub mod rpc_health;
pub mod rpc_pubsub; pub mod rpc_pubsub;
pub mod rpc_pubsub_service; pub mod rpc_pubsub_service;

View File

@ -5,7 +5,6 @@ use crate::{
contact_info::ContactInfo, contact_info::ContactInfo,
non_circulating_supply::calculate_non_circulating_supply, non_circulating_supply::calculate_non_circulating_supply,
optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank, optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
rpc_error::RpcCustomError,
rpc_health::*, rpc_health::*,
send_transaction_service::{SendTransactionService, TransactionInfo}, send_transaction_service::{SendTransactionService, TransactionInfo},
validator::ValidatorExit, validator::ValidatorExit,
@ -23,6 +22,7 @@ use solana_account_decoder::{
}; };
use solana_client::{ use solana_client::{
rpc_config::*, rpc_config::*,
rpc_custom_error::RpcCustomError,
rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType}, rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType},
rpc_request::{ rpc_request::{
TokenAccountsFilter, DELINQUENT_VALIDATOR_SLOT_DISTANCE, MAX_GET_CONFIRMED_BLOCKS_RANGE, TokenAccountsFilter, DELINQUENT_VALIDATOR_SLOT_DISTANCE, MAX_GET_CONFIRMED_BLOCKS_RANGE,