From 52404d25a64596f19594e54f401938bcc3b1fcea Mon Sep 17 00:00:00 2001 From: Mattie Conover Date: Fri, 17 Mar 2023 10:10:31 -0700 Subject: [PATCH] Better context to track down errors during init (#1911) ### Description - Additional context to error to track down what chain's configuration is invalid. ### Drive-by changes None ### Related issues - Fixes https://discord.com/channels/935678348330434570/961711527092682783/1082783165803937853 ### Backward compatibility _Are these changes backward compatible?_ Yes _Are there any infrastructure implications, e.g. changes that would prohibit deploying older commits using this infra tooling?_ None ### Testing _What kind of testing have these changes undergone?_ Manual --- .../hyperlane-ethereum/src/trait_builder.rs | 26 ++++++++++--------- rust/hyperlane-base/src/settings/mod.rs | 19 +++++++++++--- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/rust/chains/hyperlane-ethereum/src/trait_builder.rs b/rust/chains/hyperlane-ethereum/src/trait_builder.rs index 0e6263841..684f28b38 100644 --- a/rust/chains/hyperlane-ethereum/src/trait_builder.rs +++ b/rust/chains/hyperlane-ethereum/src/trait_builder.rs @@ -34,6 +34,9 @@ pub enum EthereumProviderConnectionError { /// A URL string could not be parsed #[error("Failed to parse url {1:?}: {0}")] InvalidUrl(url::ParseError, String), + /// A URL string was `""` + #[error("The url is an empty string; ensure the default configuration has been overridden")] + EmptyUrl, /// Underlying websocket library threw an error #[error(transparent)] WebsocketClientError(#[from] WsClientError), @@ -62,6 +65,7 @@ pub trait BuildableWithProvider { rpc_metrics: Option, middleware_metrics: Option<(MiddlewareMetrics, PrometheusMiddlewareConf)>, ) -> ChainResult { + use EthereumProviderConnectionError::{EmptyUrl, InvalidUrl}; Ok(match conn { ConnectionConf::HttpQuorum { urls } => { let mut builder = QuorumProvider::builder().quorum(Quorum::Majority); @@ -70,9 +74,12 @@ pub trait BuildableWithProvider { .build() .map_err(EthereumProviderConnectionError::from)?; for url in urls.split(',') { - let parsed_url = url.parse::().map_err(|e| { - EthereumProviderConnectionError::InvalidUrl(e, url.to_owned()) - })?; + if url.is_empty() { + return Err(EmptyUrl.into()); + } + let parsed_url = url + .parse::() + .map_err(|e| InvalidUrl(e, url.to_owned()))?; let http_provider = Http::new_with_client(parsed_url.clone(), http_client.clone()); // Wrap the inner providers as RetryingProviders rather than the QuorumProvider. @@ -107,16 +114,13 @@ pub trait BuildableWithProvider { .map_err(EthereumProviderConnectionError::from)?; for url in urls.split(',') { let http_provider = Http::new_with_client( - url.parse::().map_err(|e| { - EthereumProviderConnectionError::InvalidUrl(e, url.to_owned()) - })?, + url.parse::() + .map_err(|e| InvalidUrl(e, url.to_owned()))?, http_client.clone(), ); let metrics_provider = self.wrap_rpc_with_metrics( http_provider, - Url::parse(url).map_err(|e| { - EthereumProviderConnectionError::InvalidUrl(e, url.to_owned()) - })?, + Url::parse(url).map_err(|e| InvalidUrl(e, url.to_owned()))?, &rpc_metrics, &middleware_metrics, ); @@ -131,9 +135,7 @@ pub trait BuildableWithProvider { .timeout(HTTP_CLIENT_TIMEOUT) .build() .map_err(EthereumProviderConnectionError::from)?; - let parsed_url = url - .parse::() - .map_err(|e| EthereumProviderConnectionError::InvalidUrl(e, url.clone()))?; + let parsed_url = url.parse::().map_err(|e| InvalidUrl(e, url.clone()))?; let http_provider = Http::new_with_client(parsed_url.clone(), http_client); let metrics_provider = self.wrap_rpc_with_metrics( http_provider, diff --git a/rust/hyperlane-base/src/settings/mod.rs b/rust/hyperlane-base/src/settings/mod.rs index afd7ab614..c18123ead 100644 --- a/rust/hyperlane-base/src/settings/mod.rs +++ b/rust/hyperlane-base/src/settings/mod.rs @@ -186,8 +186,14 @@ impl Settings { db: DB, metrics: &CoreMetrics, ) -> eyre::Result { - let mailbox = self.build_mailbox(chain_name, metrics).await?; - let indexer = self.build_mailbox_indexer(chain_name, metrics).await?; + let mailbox = self + .build_mailbox(chain_name, metrics) + .await + .with_context(|| format!("Building mailbox for {chain_name}"))?; + let indexer = self + .build_mailbox_indexer(chain_name, metrics) + .await + .with_context(|| format!("Building mailbox indexer for {chain_name}"))?; let hyperlane_db = HyperlaneDB::new(chain_name, db); Ok(CachingMailbox::new( mailbox.into(), @@ -224,7 +230,9 @@ impl Settings { address: H256, metrics: &CoreMetrics, ) -> eyre::Result> { - let setup = self.chain_setup(chain_name)?; + let setup = self + .chain_setup(chain_name) + .with_context(|| format!("Building multisig ism for {chain_name}"))?; setup.build_multisig_ism(address, metrics).await } @@ -235,7 +243,10 @@ impl Settings { metrics: &CoreMetrics, ) -> eyre::Result> { let setup = self.chain_setup(chain_name)?; - let announce = setup.build_validator_announce(metrics).await?; + let announce = setup + .build_validator_announce(metrics) + .await + .with_context(|| format!("Building validator announce for {chain_name}"))?; Ok(announce.into()) }