From 320875156b6d4ae37badf79da5b35a4547638c5b Mon Sep 17 00:00:00 2001 From: Jono Prest Date: Tue, 23 Jul 2024 17:48:56 +0200 Subject: [PATCH] Deserialize ResponseData using status for error and success --- crates/block-explorers/src/lib.rs | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/crates/block-explorers/src/lib.rs b/crates/block-explorers/src/lib.rs index 9923707..c20b41f 100644 --- a/crates/block-explorers/src/lib.rs +++ b/crates/block-explorers/src/lib.rs @@ -241,7 +241,7 @@ impl Client { })?; match res { - ResponseData::Error { result, message, status } => { + ResponseData::Error { message, result } => { if let Some(ref result) = result { if result.starts_with("Max rate limit reached") { return Err(EtherscanError::RateLimitExceeded); @@ -250,9 +250,11 @@ impl Client { return Err(EtherscanError::InvalidApiKey); } } - Err(EtherscanError::ErrorResponse { status, message, result }) + Err(EtherscanError::ErrorResponse { status: "0".to_string(), message, result }) + } + ResponseData::Success { message, result } => { + Ok(Response { status: "1".to_string(), message, result }) } - ResponseData::Success(res) => Ok(res), } } @@ -496,11 +498,13 @@ pub struct Response { pub result: T, } -#[derive(Deserialize, Debug, Clone)] -#[serde(untagged)] +#[derive(Debug, Clone, Deserialize)] +#[serde(tag = "status")] pub enum ResponseData { - Success(Response), - Error { status: String, message: String, result: Option }, + #[serde(rename = "1")] + Success { message: String, result: T }, + #[serde(rename = "0")] + Error { message: String, result: Option }, } /// The type that gets serialized as query @@ -528,6 +532,7 @@ mod tests { use crate::{Client, EtherscanError, ResponseData}; use alloy_chains::Chain; use alloy_primitives::{Address, B256}; + use serde_json::json; // #[test] @@ -537,6 +542,17 @@ mod tests { assert!(matches!(resp, ResponseData::Error { .. })); } + #[test] + fn can_parse_etherscan_mainnet_invalid_api_key() { + let err = json!({ + "status":"0", + "message":"NOTOK", + "result":"Missing/Invalid API Key" + }); + let resp: ResponseData
= serde_json::from_value(err).unwrap(); + assert!(matches!(resp, ResponseData::Error { .. })); + } + #[test] fn test_api_paths() { let client = Client::new(Chain::goerli(), "").unwrap();