Skip to content

Commit eb32d9a

Browse files
authored
Hint when contract id looks like a wasm hash. (#2550)
1 parent 75a9426 commit eb32d9a

1 file changed

Lines changed: 63 additions & 1 deletion

File tree

cmd/soroban-cli/src/config/locator.rs

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ pub enum Error {
8585
CannotAccessAliasConfigFile,
8686
#[error("cannot parse contract ID {0}: {1}")]
8787
CannotParseContractId(String, DecodeError),
88-
#[error("contract not found: {0}")]
88+
#[error("contract not found: {0}{hint}", hint = wasm_hash_hint(.0))]
8989
ContractNotFound(String),
9090
#[error("Failed to read upgrade check file: {path}: {error}")]
9191
UpgradeCheckReadFailed { path: PathBuf, error: io::Error },
@@ -109,6 +109,14 @@ pub enum Error {
109109
InvalidSigningKey,
110110
}
111111

112+
fn wasm_hash_hint(value: &str) -> &'static str {
113+
if value.len() == 64 && value.bytes().all(|b| b.is_ascii_hexdigit()) {
114+
"; expected a contract address (C...), got a hash"
115+
} else {
116+
""
117+
}
118+
}
119+
112120
#[derive(Debug, clap::Args, Default, Clone)]
113121
#[group(skip)]
114122
pub struct Args {
@@ -928,6 +936,60 @@ pub fn cli_config_file() -> Result<PathBuf, Error> {
928936
Ok(global_config_path()?.join("config.toml"))
929937
}
930938

939+
#[cfg(test)]
940+
mod error_message_tests {
941+
use super::*;
942+
943+
#[test]
944+
fn contract_not_found_plain_alias_has_no_hint() {
945+
let err = Error::ContractNotFound("alice".to_string());
946+
assert_eq!(err.to_string(), "contract not found: alice");
947+
}
948+
949+
#[test]
950+
fn contract_not_found_64_char_lowercase_hex_includes_wasm_hash_hint() {
951+
let hash = "5ea0f3d6c880148c8da088809e851732127fc36b7b42bbdde6052fcc6f6253f3";
952+
let err = Error::ContractNotFound(hash.to_string());
953+
assert_eq!(
954+
err.to_string(),
955+
format!("contract not found: {hash}; expected a contract address (C...), got a hash"),
956+
);
957+
}
958+
959+
#[test]
960+
fn contract_not_found_64_char_uppercase_hex_includes_wasm_hash_hint() {
961+
let hash = "5EA0F3D6C880148C8DA088809E851732127FC36B7B42BBDDE6052FCC6F6253F3";
962+
let err = Error::ContractNotFound(hash.to_string());
963+
assert!(
964+
err.to_string().contains("got a hash"),
965+
"expected wasm-hash hint for uppercase hex, got: {err}",
966+
);
967+
}
968+
969+
#[test]
970+
fn contract_not_found_64_char_mixed_case_hex_includes_wasm_hash_hint() {
971+
let hash = "5ea0F3d6C880148c8DA088809e851732127fc36b7b42BBDDE6052fcc6F6253F3";
972+
let err = Error::ContractNotFound(hash.to_string());
973+
assert!(
974+
err.to_string().contains("got a hash"),
975+
"expected wasm-hash hint for mixed-case hex, got: {err}",
976+
);
977+
}
978+
979+
#[test]
980+
fn contract_not_found_short_hex_string_has_no_hint() {
981+
let err = Error::ContractNotFound("deadbeef".to_string());
982+
assert_eq!(err.to_string(), "contract not found: deadbeef");
983+
}
984+
985+
#[test]
986+
fn contract_not_found_64_char_non_hex_has_no_hint() {
987+
let value = "z".repeat(64);
988+
let err = Error::ContractNotFound(value.clone());
989+
assert_eq!(err.to_string(), format!("contract not found: {value}"));
990+
}
991+
}
992+
931993
#[cfg(all(test, unix))]
932994
mod tests {
933995
use super::*;

0 commit comments

Comments
 (0)