Skip to content

Commit

Permalink
chore(cast): better error handling (foundry-rs#3474)
Browse files Browse the repository at this point in the history
* chore: remove consume_config_rpc_url

* chore: improve cast tx, receipt, run error handling

* chore: use debug fmt
  • Loading branch information
DaniPopes authored Oct 11, 2022
1 parent e9eab88 commit 72b0c5d
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 193 deletions.
89 changes: 34 additions & 55 deletions cast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,30 +561,22 @@ where
field: Option<String>,
to_json: bool,
) -> Result<String> {
let transaction_result = self
let tx_hash = H256::from_str(&tx_hash).wrap_err("invalid tx hash")?;
let tx = self
.provider
.get_transaction(H256::from_str(&tx_hash)?)
.get_transaction(tx_hash)
.await?
.ok_or_else(|| eyre::eyre!("transaction {:?} not found", tx_hash))?;
.ok_or_else(|| eyre::eyre!("tx not found: {:?}", tx_hash))?;

let transaction = if let Some(ref field) = field {
serde_json::to_value(&transaction_result)?
.get(field)
.cloned()
.ok_or_else(|| eyre::eyre!("field {field} not found"))?
} else {
serde_json::to_value(&transaction_result)?
};

let transaction = if let Some(ref field) = field {
get_pretty_tx_attr(&transaction_result, field)
.unwrap_or_else(|| format!("{field} is not a valid tx field"))
Ok(if let Some(ref field) = field {
get_pretty_tx_attr(&tx, field)
.ok_or_else(|| eyre::eyre!("invalid tx field: {}", field))?
} else if to_json {
serde_json::to_string(&transaction)?
// to_value first to sort json object keys
serde_json::to_value(&tx)?.to_string()
} else {
transaction_result.pretty()
};
Ok(transaction)
tx.pretty()
})
}

/// # Example
Expand All @@ -611,49 +603,36 @@ where
cast_async: bool,
to_json: bool,
) -> Result<String> {
let tx_hash = H256::from_str(&tx_hash)?;

// try to get the receipt
let receipt = self.provider.get_transaction_receipt(tx_hash).await?;

// if the async flag is provided, immediately exit if no tx is found,
// otherwise try to poll for it
let receipt_result = if cast_async {
match receipt {
Some(inner) => inner,
None => return Ok("receipt not found".to_string()),
}
} else {
match receipt {
Some(inner) => inner,
None => {
let tx_hash = H256::from_str(&tx_hash).wrap_err("invalid tx hash")?;

let receipt = match self.provider.get_transaction_receipt(tx_hash).await? {
Some(r) => r,
None => {
// if the async flag is provided, immediately exit if no tx is found, otherwise try
// to poll for it
if cast_async {
eyre::bail!("tx not found: {:?}", tx_hash)
} else {
let tx = PendingTransaction::new(tx_hash, self.provider.provider());
match tx.confirmations(confs).await? {
Some(inner) => inner,
None => return Ok("receipt not found when polling pending tx. was the transaction dropped from the mempool?".to_string())
}
tx.confirmations(confs).await?.ok_or_else(|| {
eyre::eyre!(
"tx not found, might have been dropped from mempool: {:?}",
tx_hash
)
})?
}
}
};

let receipt = if let Some(ref field) = field {
serde_json::to_value(&receipt_result)?
.get(field)
.cloned()
.ok_or_else(|| eyre::eyre!("field {field} not found"))?
} else {
serde_json::to_value(&receipt_result)?
};

let receipt = if let Some(ref field) = field {
get_pretty_tx_receipt_attr(&receipt_result, field)
.unwrap_or_else(|| format!("{field} is not a valid tx receipt field"))
Ok(if let Some(ref field) = field {
get_pretty_tx_receipt_attr(&receipt, field)
.ok_or_else(|| eyre::eyre!("invalid receipt field: {}", field))?
} else if to_json {
serde_json::to_string(&receipt)?
// to_value first to sort json object keys
serde_json::to_value(&receipt)?.to_string()
} else {
receipt_result.pretty()
};
Ok(receipt)
receipt.pretty()
})
}

/// Perform a raw JSON-RPC request
Expand Down
8 changes: 4 additions & 4 deletions cli/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,22 +315,22 @@ async fn main() -> eyre::Result<()> {
println!("{}", serde_json::json!(receipt));
}
}
Subcommands::Receipt { hash, field, to_json, rpc_url, cast_async, confirmations } => {
Subcommands::Receipt { tx_hash, field, to_json, rpc_url, cast_async, confirmations } => {
let rpc_url = try_consume_config_rpc_url(rpc_url)?;
let provider = try_get_http_provider(rpc_url)?;
println!(
"{}",
Cast::new(provider)
.receipt(hash, field, confirmations, cast_async, to_json)
.receipt(tx_hash, field, confirmations, cast_async, to_json)
.await?
);
}
Subcommands::Run(cmd) => cmd.run()?,
Subcommands::SendTx(cmd) => cmd.run().await?,
Subcommands::Tx { rpc_url, hash, field, to_json } => {
Subcommands::Tx { rpc_url, tx_hash, field, to_json } => {
let rpc_url = try_consume_config_rpc_url(rpc_url)?;
let provider = try_get_http_provider(rpc_url)?;
println!("{}", Cast::new(&provider).transaction(hash, field, to_json).await?)
println!("{}", Cast::new(&provider).transaction(tx_hash, field, to_json).await?)
}

// 4Byte
Expand Down
4 changes: 2 additions & 2 deletions cli/src/cmd/cast/find_block.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! cast find-block subcommand
use crate::{cmd::Cmd, utils::consume_config_rpc_url};
use crate::{cmd::Cmd, utils::try_consume_config_rpc_url};
use cast::Cast;
use clap::Parser;
use ethers::prelude::*;
Expand Down Expand Up @@ -28,7 +28,7 @@ impl Cmd for FindBlockArgs {
impl FindBlockArgs {
async fn query_block(timestamp: u64, rpc_url: Option<String>) -> Result<()> {
let ts_target = U256::from(timestamp);
let rpc_url = consume_config_rpc_url(rpc_url);
let rpc_url = try_consume_config_rpc_url(rpc_url)?;

let provider = try_get_http_provider(rpc_url)?;
let last_block_num = provider.get_block_number().await?;
Expand Down
4 changes: 2 additions & 2 deletions cli/src/cmd/cast/rpc.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{cmd::Cmd, utils::consume_config_rpc_url};
use crate::{cmd::Cmd, utils::try_consume_config_rpc_url};
use cast::Cast;
use clap::Parser;
use eyre::Result;
Expand Down Expand Up @@ -52,7 +52,7 @@ impl RpcArgs {
method: String,
params: Vec<String>,
) -> Result<()> {
let rpc_url = consume_config_rpc_url(rpc_url);
let rpc_url = try_consume_config_rpc_url(rpc_url)?;
let provider = try_get_http_provider(rpc_url)?;
let params = if raw {
if params.is_empty() {
Expand Down
Loading

0 comments on commit 72b0c5d

Please sign in to comment.