Rename RpcNodeUnhealthy error to NodeUnhealthy, generalize getHealth RPC error object for the future

This commit is contained in:
Michael Vines
2021-01-17 20:23:14 -08:00
parent cbf8ef7480
commit 5d9dc609b1
6 changed files with 45 additions and 22 deletions

View File

@ -86,8 +86,8 @@ impl RpcSender for HttpSender {
} }
}, },
rpc_custom_error::JSON_RPC_SERVER_ERROR_NODE_UNHEALTHLY => { rpc_custom_error::JSON_RPC_SERVER_ERROR_NODE_UNHEALTHLY => {
match serde_json::from_value::<rpc_custom_error::RpcNodeUnhealthyErrorData>(json["error"]["data"].clone()) { match serde_json::from_value::<rpc_custom_error::NodeUnhealthyErrorData>(json["error"]["data"].clone()) {
Ok(rpc_custom_error::RpcNodeUnhealthyErrorData { num_slots_behind}) => RpcResponseErrorData::NodeUnhealthy {num_slots_behind}, Ok(rpc_custom_error::NodeUnhealthyErrorData {num_slots_behind}) => RpcResponseErrorData::NodeUnhealthy {num_slots_behind},
Err(_err) => { Err(_err) => {
RpcResponseErrorData::Empty RpcResponseErrorData::Empty
} }

View File

@ -26,8 +26,8 @@ pub enum RpcCustomError {
BlockNotAvailable { BlockNotAvailable {
slot: Slot, slot: Slot,
}, },
RpcNodeUnhealthy { NodeUnhealthy {
num_slots_behind: Slot, num_slots_behind: Option<Slot>,
}, },
TransactionPrecompileVerificationFailure(solana_sdk::transaction::TransactionError), TransactionPrecompileVerificationFailure(solana_sdk::transaction::TransactionError),
SlotSkipped { SlotSkipped {
@ -38,8 +38,8 @@ pub enum RpcCustomError {
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RpcNodeUnhealthyErrorData { pub struct NodeUnhealthyErrorData {
pub num_slots_behind: Slot, pub num_slots_behind: Option<Slot>,
} }
impl From<RpcCustomError> for Error { impl From<RpcCustomError> for Error {
@ -75,10 +75,14 @@ impl From<RpcCustomError> for Error {
message: format!("Block not available for slot {}", slot), message: format!("Block not available for slot {}", slot),
data: None, data: None,
}, },
RpcCustomError::RpcNodeUnhealthy { num_slots_behind } => Self { RpcCustomError::NodeUnhealthy { num_slots_behind } => Self {
code: ErrorCode::ServerError(JSON_RPC_SERVER_ERROR_NODE_UNHEALTHLY), code: ErrorCode::ServerError(JSON_RPC_SERVER_ERROR_NODE_UNHEALTHLY),
message: format!("RPC node is behind by {} slots", num_slots_behind), message: if let Some(num_slots_behind) = num_slots_behind {
data: Some(serde_json::json!(RpcNodeUnhealthyErrorData { format!("Node is behind by {} slots", num_slots_behind)
} else {
"Node is unhealthy".to_string()
},
data: Some(serde_json::json!(NodeUnhealthyErrorData {
num_slots_behind num_slots_behind
})), })),
}, },

View File

@ -147,7 +147,7 @@ impl RpcRequest {
pub enum RpcResponseErrorData { pub enum RpcResponseErrorData {
Empty, Empty,
SendTransactionPreflightFailure(RpcSimulateTransactionResult), SendTransactionPreflightFailure(RpcSimulateTransactionResult),
NodeUnhealthy { num_slots_behind: Slot }, NodeUnhealthy { num_slots_behind: Option<Slot> },
} }
impl fmt::Display for RpcResponseErrorData { impl fmt::Display for RpcResponseErrorData {

View File

@ -2265,9 +2265,10 @@ impl RpcSol for RpcSolImpl {
fn get_health(&self, meta: Self::Metadata) -> Result<String> { fn get_health(&self, meta: Self::Metadata) -> Result<String> {
match meta.health.check() { match meta.health.check() {
RpcHealthStatus::Ok => Ok("ok".to_string()), RpcHealthStatus::Ok => Ok("ok".to_string()),
RpcHealthStatus::Behind { RpcHealthStatus::Behind { num_slots } => Err(RpcCustomError::NodeUnhealthy {
num_slots: num_slots_behind, num_slots_behind: Some(num_slots),
} => Err(RpcCustomError::RpcNodeUnhealthy { num_slots_behind }.into()), }
.into()),
} }
} }
@ -2523,10 +2524,11 @@ impl RpcSol for RpcSolImpl {
match meta.health.check() { match meta.health.check() {
RpcHealthStatus::Ok => (), RpcHealthStatus::Ok => (),
RpcHealthStatus::Behind { RpcHealthStatus::Behind { num_slots } => {
num_slots: num_slots_behind, return Err(RpcCustomError::NodeUnhealthy {
} => { num_slots_behind: Some(num_slots),
return Err(RpcCustomError::RpcNodeUnhealthy { num_slots_behind }.into()); }
.into());
} }
} }
@ -4570,7 +4572,7 @@ pub mod tests {
assert_eq!( assert_eq!(
res, res,
Some( Some(
r#"{"jsonrpc":"2.0","error":{"code":-32005,"message":"RPC node is behind by 42 slots","data":{"numSlotsBehind":42}},"id":1}"#.to_string(), r#"{"jsonrpc":"2.0","error":{"code":-32005,"message":"Node is behind by 42 slots","data":{"numSlotsBehind":42}},"id":1}"#.to_string(),
) )
); );
health.stub_set_health_status(None); health.stub_set_health_status(None);

View File

@ -1294,7 +1294,9 @@ None
#### Results: #### Results:
If the node is healthy: "ok" If the node is healthy: "ok"
If the node is unhealthy, a JSON RPC error response is returned indicating how far behind the node is. If the node is unhealthy, a JSON RPC error response is returned. The specifics
of the error response are **UNSTABLE** and may change in the future
#### Example: #### Example:
@ -1310,13 +1312,26 @@ Healthy Result:
{"jsonrpc":"2.0","result": "ok","id":1} {"jsonrpc":"2.0","result": "ok","id":1}
``` ```
Unhealthy Result: Unhealthy Result (generic):
```json ```json
{ {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"error": { "error": {
"code": -32005, "code": -32005,
"message": "RPC node is behind by 42 slots", "message": "Node is unhealthy",
"data": {}
},
"id": 1
}
```
Unhealthy Result (if additional information is available)
```json
{
"jsonrpc": "2.0",
"error": {
"code": -32005,
"message": "Node is behind by 42 slots",
"data": { "data": {
"numSlotsBehind": 42 "numSlotsBehind": 42
} }

View File

@ -358,7 +358,9 @@ fn main() {
code: _, code: _,
message: _, message: _,
data: data:
rpc_request::RpcResponseErrorData::NodeUnhealthy { num_slots_behind }, rpc_request::RpcResponseErrorData::NodeUnhealthy {
num_slots_behind: Some(num_slots_behind),
},
}, },
) = &err.kind ) = &err.kind
{ {