From: Jeffrey Czyz Date: Wed, 26 May 2021 17:57:39 +0000 (-0700) Subject: Parse RPC errors as JSON content X-Git-Tag: v0.0.98~16^2 X-Git-Url: http://git.bitcoin.ninja/?a=commitdiff_plain;h=b2f16ad821672e07fd588beecd117206d9b656fd;p=rust-lightning Parse RPC errors as JSON content Bitcoin Core's JSON RPC server returns errors as HTTP error responses with JSON content in the body. Parse this content as JSON to give a more meaningful error. Otherwise, "binary" is given because the content contains ASCII control characters. --- diff --git a/lightning-block-sync/src/rpc.rs b/lightning-block-sync/src/rpc.rs index 66570bcb5..88199688a 100644 --- a/lightning-block-sync/src/rpc.rs +++ b/lightning-block-sync/src/rpc.rs @@ -2,7 +2,7 @@ //! endpoint. use crate::{BlockHeaderData, BlockSource, AsyncBlockSourceResult}; -use crate::http::{HttpClient, HttpEndpoint, JsonResponse}; +use crate::http::{HttpClient, HttpEndpoint, HttpError, JsonResponse}; use bitcoin::blockdata::block::Block; use bitcoin::hash_types::BlockHash; @@ -47,8 +47,20 @@ impl RpcClient { "id": &self.id.fetch_add(1, Ordering::AcqRel).to_string() }); - let mut response = self.client.post::(&uri, &host, &self.basic_auth, content) - .await?.0; + let mut response = match self.client.post::(&uri, &host, &self.basic_auth, content).await { + Ok(JsonResponse(response)) => response, + Err(e) if e.kind() == std::io::ErrorKind::Other => { + match e.get_ref().unwrap().downcast_ref::() { + Some(http_error) => match JsonResponse::try_from(http_error.contents.clone()) { + Ok(JsonResponse(response)) => response, + Err(_) => Err(e)?, + }, + None => Err(e)?, + } + }, + Err(e) => Err(e)?, + }; + if !response.is_object() { return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "expected JSON object")); } @@ -143,7 +155,7 @@ mod tests { let response = serde_json::json!({ "error": { "code": -8, "message": "invalid parameter" }, }); - let server = HttpServer::responding_with_ok(MessageBody::Content(response)); + let server = HttpServer::responding_with_server_error(response); let mut client = RpcClient::new(CREDENTIALS, server.endpoint()).unwrap(); let invalid_block_hash = serde_json::json!("foo");