diff --git a/crates/sncast/src/main.rs b/crates/sncast/src/main.rs index 7daa0a202d..f4efbecc6a 100644 --- a/crates/sncast/src/main.rs +++ b/crates/sncast/src/main.rs @@ -311,7 +311,7 @@ async fn run_async_command(cli: Cli, config: CastConfig, ui: &UI) -> Result<()> let block_explorer_link = block_explorer_link_if_allowed(&result, provider.chain_id().await?, &rpc, &config); - process_command_result("declare", result, ui, block_explorer_link); + process_command_result("declare", result, ui, block_explorer_link)?; Ok(()) } @@ -353,7 +353,7 @@ async fn run_async_command(cli: Cli, config: CastConfig, ui: &UI) -> Result<()> &rpc_args, &config, ); - process_command_result("declare-from", result, ui, block_explorer_link); + process_command_result("declare-from", result, ui, block_explorer_link)?; Ok(()) } @@ -400,7 +400,7 @@ async fn run_async_command(cli: Cli, config: CastConfig, ui: &UI) -> Result<()> let block_explorer_link = block_explorer_link_if_allowed(&result, provider.chain_id().await?, &rpc, &config); - process_command_result("deploy", result, ui, block_explorer_link); + process_command_result("deploy", result, ui, block_explorer_link)?; Ok(()) } @@ -436,9 +436,9 @@ async fn run_async_command(cli: Cli, config: CastConfig, ui: &UI) -> Result<()> if let Some(transformed_result) = transform_response(&result, &contract_class, &selector) { - process_command_result("call", Ok(transformed_result), ui, None); + process_command_result("call", Ok(transformed_result), ui, None)?; } else { - process_command_result("call", result, ui, None); + process_command_result("call", result, ui, None)?; } Ok(()) @@ -489,7 +489,7 @@ async fn run_async_command(cli: Cli, config: CastConfig, ui: &UI) -> Result<()> let block_explorer_link = block_explorer_link_if_allowed(&result, provider.chain_id().await?, &rpc, &config); - process_command_result("invoke", result, ui, block_explorer_link); + process_command_result("invoke", result, ui, block_explorer_link)?; Ok(()) } @@ -522,7 +522,7 @@ async fn run_async_command(cli: Cli, config: CastConfig, ui: &UI) -> Result<()> ) .await; - process_command_result("show-config", result, ui, None); + process_command_result("show-config", result, ui, None)?; Ok(()) } @@ -535,7 +535,7 @@ async fn run_async_command(cli: Cli, config: CastConfig, ui: &UI) -> Result<()> .await .context("Failed to get transaction status"); - process_command_result("tx-status", result, ui, None); + process_command_result("tx-status", result, ui, None)?; Ok(()) } @@ -562,7 +562,7 @@ async fn run_async_command(cli: Cli, config: CastConfig, ui: &UI) -> Result<()> ) .await; - process_command_result("verify", result, ui, None); + process_command_result("verify", result, ui, None)?; Ok(()) } @@ -637,7 +637,8 @@ fn process_command_result( result: Result, ui: &UI, block_explorer_link: Option, -) where +) -> Result<()> +where T: CommandResponse, SncastMessage: Message, { @@ -652,10 +653,12 @@ fn process_command_result( if let Some(link) = block_explorer_link { ui.println(&link); } + Ok(()) } Err(err) => { - let err = ResponseError::new(command.to_string(), format!("{err:#}")); - ui.eprintln(&err); + let response_err = ResponseError::new(command.to_string(), format!("{err:#}")); + ui.eprintln(&response_err); + Err(err) } } } diff --git a/crates/sncast/src/starknet_commands/account/mod.rs b/crates/sncast/src/starknet_commands/account/mod.rs index 5e3db05867..850d82efc3 100644 --- a/crates/sncast/src/starknet_commands/account/mod.rs +++ b/crates/sncast/src/starknet_commands/account/mod.rs @@ -231,7 +231,7 @@ pub async fn account( )); } - process_command_result("account import", result, ui, None); + process_command_result("account import", result, ui, None)?; Ok(()) } Commands::Create(create) => { @@ -264,7 +264,7 @@ pub async fn account( &config, ); - process_command_result("account create", result, ui, block_explorer_link); + process_command_result("account create", result, ui, block_explorer_link)?; Ok(()) } @@ -311,7 +311,7 @@ pub async fn account( &deploy.rpc, &config, ); - process_command_result("account deploy", result, ui, block_explorer_link); + process_command_result("account deploy", result, ui, block_explorer_link)?; Ok(()) } @@ -326,7 +326,7 @@ pub async fn account( delete.yes, ); - process_command_result("account delete", result, ui, None); + process_command_result("account delete", result, ui, None)?; Ok(()) } diff --git a/crates/sncast/src/starknet_commands/multicall/mod.rs b/crates/sncast/src/starknet_commands/multicall/mod.rs index 2642f0540a..0aee849e54 100644 --- a/crates/sncast/src/starknet_commands/multicall/mod.rs +++ b/crates/sncast/src/starknet_commands/multicall/mod.rs @@ -42,7 +42,7 @@ pub async fn multicall( new.overwrite, ); - process_command_result("multicall new", result, ui, None); + process_command_result("multicall new", result, ui, None)?; } else { ui.println(&DEFAULT_MULTICALL_CONTENTS); } @@ -68,7 +68,7 @@ pub async fn multicall( &run.rpc, &config, ); - process_command_result("multicall run", result, ui, block_explorer_link); + process_command_result("multicall run", result, ui, block_explorer_link)?; Ok(()) } } diff --git a/crates/sncast/src/starknet_commands/script/mod.rs b/crates/sncast/src/starknet_commands/script/mod.rs index 977de56adb..4974d1aea5 100644 --- a/crates/sncast/src/starknet_commands/script/mod.rs +++ b/crates/sncast/src/starknet_commands/script/mod.rs @@ -34,7 +34,7 @@ pub fn run_script_command( match &script.command { starknet_commands::script::Commands::Init(init) => { let result = starknet_commands::script::init::init(init, ui); - process_command_result("script init", result, ui, None); + process_command_result("script init", result, ui, None)?; } starknet_commands::script::Commands::Run(run) => { let manifest_path = assert_manifest_path_exists()?; @@ -90,7 +90,7 @@ pub fn run_script_command( ui, ); - process_command_result("script run", result, ui, None); + process_command_result("script run", result, ui, None)?; } } diff --git a/crates/sncast/src/starknet_commands/utils/mod.rs b/crates/sncast/src/starknet_commands/utils/mod.rs index 69c32a7cfb..a69ca83237 100644 --- a/crates/sncast/src/starknet_commands/utils/mod.rs +++ b/crates/sncast/src/starknet_commands/utils/mod.rs @@ -50,7 +50,7 @@ pub async fn utils( .await .map_err(handle_starknet_command_error)?; - process_command_result("serialize", Ok(result), ui, None); + process_command_result("serialize", Ok(result), ui, None)?; } Commands::ClassHash(class_hash) => { @@ -72,7 +72,7 @@ pub async fn utils( let result = class_hash::get_class_hash(&class_hash, &artifacts) .map_err(handle_starknet_command_error)?; - process_command_result("class-hash", Ok(result), ui, None); + process_command_result("class-hash", Ok(result), ui, None)?; } } diff --git a/crates/sncast/tests/integration/exit_codes.rs b/crates/sncast/tests/integration/exit_codes.rs new file mode 100644 index 0000000000..30222a7b9e --- /dev/null +++ b/crates/sncast/tests/integration/exit_codes.rs @@ -0,0 +1,41 @@ +use crate::helpers::runner::runner; + +#[test] +fn test_exit_code_success() { + let args = vec!["show-config"]; + let snapbox = runner(&args); + snapbox.assert().success(); +} + +#[test] +fn test_exit_code_invalid_command() { + let args = vec!["invalid-command"]; + let snapbox = runner(&args); + let output = snapbox.assert().code(2); + assert!(String::from_utf8_lossy(&output.get_output().stderr) + .contains("unrecognized subcommand")); +} + +#[test] +fn test_exit_code_rpc_error() { + let args = vec![ + "call", + "--url", + "http://invalid-url-that-does-not-exist", + "--contract-address", + "0x0", + "--function", + "test", + ]; + let snapbox = runner(&args); + snapbox.assert().code(1); +} + +#[test] +fn test_exit_code_missing_required_arg() { + let args = vec!["call"]; + let snapbox = runner(&args); + let output = snapbox.assert().code(2); + assert!(String::from_utf8_lossy(&output.get_output().stderr) + .contains("required arguments were not provided")); +} diff --git a/crates/sncast/tests/integration/mod.rs b/crates/sncast/tests/integration/mod.rs index ccbb1d5946..2ce76b14d2 100644 --- a/crates/sncast/tests/integration/mod.rs +++ b/crates/sncast/tests/integration/mod.rs @@ -1,3 +1,4 @@ +mod exit_codes; mod fee; mod lib_tests; mod wait_for_tx;