diff --git a/crates/config/src/etherscan.rs b/crates/config/src/etherscan.rs index 5999825e94681..d100248ad5edd 100644 --- a/crates/config/src/etherscan.rs +++ b/crates/config/src/etherscan.rs @@ -138,14 +138,35 @@ impl ResolvedEtherscanConfigs { self, chain: Chain, ) -> Option> { + let mut first_error: Option = None; + let mut matching_chain_error: Option = None; + for (_, config) in self.configs.into_iter() { match config { - Ok(c) if c.chain == Some(chain) => return Some(Ok(c)), - Err(e) => return Some(Err(e)), - _ => continue, + Ok(c) => { + if c.chain == Some(chain) { + return Some(Ok(c)); + } + } + Err(e) => { + if matching_chain_error.is_none() + && let EtherscanConfigError::UnknownChain(_, c) = &e + && *c == chain + { + matching_chain_error = Some(e); + continue; + } + if first_error.is_none() { + first_error = Some(e); + } + } } } - None + + if let Some(e) = matching_chain_error { + return Some(Err(e)); + } + first_error.map(Err) } /// Returns true if there's a config that couldn't be resolved diff --git a/crates/config/src/lib.rs b/crates/config/src/lib.rs index 44c0c3620a25d..3b1d24ea138b5 100644 --- a/crates/config/src/lib.rs +++ b/crates/config/src/lib.rs @@ -3272,6 +3272,77 @@ mod tests { }); } + #[test] + fn test_find_chain_prefers_matching_ok_over_unrelated_err() { + figment::Jail::expect_with(|jail| { + jail.create_file( + "foundry.toml", + r#" + [profile.default] + + [etherscan] + bad = { key = "${UNSET_ENV}" } + mainnet = { key = "KEY", chain = 1 } + "#, + )?; + + let config = Config::load().unwrap(); + let res = config.get_etherscan_config_with_chain(Some(NamedChain::Mainnet.into())); + assert!(res.is_ok()); + let cfg = res.unwrap().unwrap(); + assert_eq!(cfg.chain, Some(NamedChain::Mainnet.into())); + assert_eq!(cfg.key, "KEY"); + + Ok(()) + }); + } + + #[test] + fn test_find_chain_prefers_matching_unknown_chain_error() { + figment::Jail::expect_with(|jail| { + jail.create_file( + "foundry.toml", + r#" + [profile.default] + + [etherscan] + bad = { key = "${UNSET_ENV}" } + wrong = { chain = 3658348, key = "foo" } + "#, + )?; + + let config = Config::load().unwrap(); + let unknown_chain = Chain::from_id(3658348); + let res = config.get_etherscan_config_with_chain(Some(unknown_chain)); + assert!(res.is_err()); + let err_msg = res.unwrap_err().to_string(); + assert!(err_msg.contains("No known Etherscan API URL for chain `3658348`")); + + Ok(()) + }); + } + + #[test] + fn test_find_chain_no_match_unrelated_err_bubbles() { + figment::Jail::expect_with(|jail| { + jail.create_file( + "foundry.toml", + r#" + [profile.default] + + [etherscan] + bad = { key = "${UNSET_ENV}" } + "#, + )?; + + let config = Config::load().unwrap(); + let res = config.get_etherscan_config_with_chain(Some(NamedChain::Arbitrum.into())); + assert!(res.is_err()); + + Ok(()) + }); + } + #[test] fn test_resolve_etherscan_with_versions() { figment::Jail::expect_with(|jail| {