Skip to content

Commit

Permalink
feat: retry unresolved env vars (foundry-rs#2516)
Browse files Browse the repository at this point in the history
* feat: retry unresolved env vars

* test: update tests
  • Loading branch information
mattsse authored and iFrostizz committed Nov 9, 2022
1 parent 7e988ba commit 9e7eb89
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 6 deletions.
24 changes: 21 additions & 3 deletions config/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,11 @@ impl RpcEndpoint {
// loop over all placeholders in the input and replace them one by one
for caps in RE_PLACEHOLDER.captures_iter(input) {
let var = &caps["inner"];
let value = env::var(var)
.map_err(|source| UnresolvedEnvVarError { var: var.to_string(), source })?;
let value = env::var(var).map_err(|source| UnresolvedEnvVarError {
unresolved: input.to_string(),
var: var.to_string(),
source,
})?;

res = res.replacen(&caps["outer"], &value, 1);
}
Expand Down Expand Up @@ -178,15 +181,30 @@ impl Deref for ResolvedRpcEndpoints {
/// Error when we failed to resolve an env var
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UnresolvedEnvVarError {
/// The unresolved input string
pub unresolved: String,
/// Var that couldn't be resolved
pub var: String,
/// the `env::var` error
pub source: VarError,
}

// === impl UnresolvedEnvVarError ===

impl UnresolvedEnvVarError {
/// Tries to resolve the RPC endpoint again
pub fn try_resolve_endpoint(&self) -> Result<String, UnresolvedEnvVarError> {
RpcEndpoint::interpolate(&self.unresolved)
}
}

impl fmt::Display for UnresolvedEnvVarError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Failed to resolve env var `{}`: {}", self.var, self.source)
write!(
f,
"Failed to resolve env var `{}` in `{}`: {}",
self.unresolved, self.var, self.source
)
}
}

Expand Down
8 changes: 7 additions & 1 deletion evm/src/executor/inspector/cheatcodes/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,13 @@ impl CheatsConfig {
let url_or_alias = url_or_alias.into();
match self.rpc_endpoints.get(&url_or_alias) {
Some(Ok(url)) => Ok(url.clone()),
Some(Err(err)) => Err(util::encode_error(err)),
Some(Err(err)) => {
// try resolve again, by checking if env vars are now set
if let Ok(url) = err.try_resolve_endpoint() {
return Ok(url)
}
Err(util::encode_error(err))
}
None => {
if !url_or_alias.starts_with("http") && !url_or_alias.starts_with("ws") {
Err(util::encode_error(format!("invalid rpc url {}", url_or_alias)))
Expand Down
4 changes: 2 additions & 2 deletions testdata/cheats/RpcUrls.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ contract RpcUrlTest is DSTest {

// returns an error if env alias does not exists
function testRevertsOnMissingEnv() public {
cheats.expectRevert("Failed to resolve env var `RPC_ENV_ALIAS`: environment variable not found");
cheats.expectRevert("Failed to resolve env var `${RPC_ENV_ALIAS}` in `RPC_ENV_ALIAS`: environment variable not found");
string memory url = cheats.rpcUrl("rpcEnvAlias");
}

// can set env and return correct url
function testCanSetAndGetURLAndAllUrls() public {
// this will fail because alias is not set
cheats.expectRevert("Failed to resolve env var `RPC_ENV_ALIAS`: environment variable not found");
cheats.expectRevert("Failed to resolve env var `${RPC_ENV_ALIAS}` in `RPC_ENV_ALIAS`: environment variable not found");
string[2][] memory _urls = cheats.rpcUrls();

string memory url = cheats.rpcUrl("rpcAlias");
Expand Down

0 comments on commit 9e7eb89

Please sign in to comment.