From 73b54a3cf97e7155c878ef4160e706a76664f97b Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Thu, 20 Jul 2023 15:15:09 +0200 Subject: [PATCH 1/3] Exit early when trigger process fails Signed-off-by: Ryan Levick --- src/commands/up.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/up.rs b/src/commands/up.rs index 0460f2c78..15f61e4fd 100644 --- a/src/commands/up.rs +++ b/src/commands/up.rs @@ -206,7 +206,7 @@ impl UpCommand { if status.success() { Ok(()) } else { - bail!(status); + std::process::exit(status.code().unwrap_or(1)) } } From cab33829c2e8392cce15088e4776a33efcfe9328 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Tue, 25 Jul 2023 18:53:33 +0200 Subject: [PATCH 2/3] Move to downcasting an error Signed-off-by: Ryan Levick --- crates/terminal/src/lib.rs | 1 - src/bin/spin.rs | 6 +++++- src/commands/up.rs | 2 +- src/lib.rs | 3 ++- src/subprocess.rs | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 src/subprocess.rs diff --git a/crates/terminal/src/lib.rs b/crates/terminal/src/lib.rs index 22fe9fdc4..dd7f151d4 100644 --- a/crates/terminal/src/lib.rs +++ b/crates/terminal/src/lib.rs @@ -75,7 +75,6 @@ fn color_choice(stream: atty::Stream) -> termcolor::ColorChoice { #[macro_export] macro_rules! step { ($step:expr, $($arg:tt)*) => {{ - $crate::cprint!($crate::colors::bold_green(), $step); print!(" "); println!($($arg)*); diff --git a/src/bin/spin.rs b/src/bin/spin.rs index ee2988a2f..f95b706d0 100644 --- a/src/bin/spin.rs +++ b/src/bin/spin.rs @@ -2,7 +2,6 @@ use anyhow::Error; use clap::{CommandFactory, FromArgMatches, Parser, Subcommand}; use is_terminal::IsTerminal; use lazy_static::lazy_static; -use spin_cli::build_info::*; use spin_cli::commands::external::predefined_externals; use spin_cli::commands::{ build::BuildCommand, @@ -16,6 +15,7 @@ use spin_cli::commands::{ up::UpCommand, watch::WatchCommand, }; +use spin_cli::{build_info::*, subprocess::ExitStatusError}; use spin_redis_engine::RedisTrigger; use spin_trigger::cli::help::HelpArgsOnlyTrigger; use spin_trigger::cli::TriggerExecutorCommand; @@ -24,6 +24,10 @@ use spin_trigger_http::HttpTrigger; #[tokio::main] async fn main() { if let Err(err) = _main().await { + if let Some(e) = err.downcast_ref::() { + std::process::exit(e.code()) + } + terminal::error!("{err}"); print_error_chain(err); std::process::exit(1) diff --git a/src/commands/up.rs b/src/commands/up.rs index 15f61e4fd..bb17cdcf6 100644 --- a/src/commands/up.rs +++ b/src/commands/up.rs @@ -206,7 +206,7 @@ impl UpCommand { if status.success() { Ok(()) } else { - std::process::exit(status.code().unwrap_or(1)) + Err(crate::subprocess::ExitStatusError::new(status).into()) } } diff --git a/src/lib.rs b/src/lib.rs index c5284f7f6..f2becb44a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,8 @@ pub mod build_info; pub mod commands; pub(crate) mod opts; +pub mod subprocess; mod watch_filter; mod watch_state; -pub use crate::opts::HELP_ARGS_ONLY_TRIGGER_TYPE; +pub use opts::HELP_ARGS_ONLY_TRIGGER_TYPE; diff --git a/src/subprocess.rs b/src/subprocess.rs new file mode 100644 index 000000000..cc6b4d93c --- /dev/null +++ b/src/subprocess.rs @@ -0,0 +1,34 @@ +/// An error representing a subprocess that errored +/// +/// This can be used to propogate a subprocesses exit status. +/// When this error is encountered the cli will exit with the status code +/// instead of printing an error, +#[derive(Debug)] +pub struct ExitStatusError { + status: Option, +} + +impl ExitStatusError { + pub(crate) fn new(status: std::process::ExitStatus) -> Self { + Self { + status: status.code(), + } + } + + pub fn code(&self) -> i32 { + self.status.unwrap_or(1) + } +} + +impl std::error::Error for ExitStatusError {} + +impl std::fmt::Display for ExitStatusError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let _ = write!(f, "subprocess exited with status: "); + if let Some(status) = self.status { + writeln!(f, "{}", status) + } else { + writeln!(f, "unknown") + } + } +} From 966113ff59cc3b1d554d8bd11786480e8f581521 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Tue, 25 Jul 2023 19:10:02 +0200 Subject: [PATCH 3/3] Add some comments Signed-off-by: Ryan Levick --- src/bin/spin.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/bin/spin.rs b/src/bin/spin.rs index f95b706d0..a8a8a96f0 100644 --- a/src/bin/spin.rs +++ b/src/bin/spin.rs @@ -24,13 +24,20 @@ use spin_trigger_http::HttpTrigger; #[tokio::main] async fn main() { if let Err(err) = _main().await { - if let Some(e) = err.downcast_ref::() { - std::process::exit(e.code()) - } + let code = match err.downcast_ref::() { + // If we encounter an `ExitStatusError` it means a subprocess has already + // exited unsuccessfully and thus already printed error messages. No need + // to print anything additional. + Some(e) => e.code(), + // Otherwise we print the error chain. + None => { + terminal::error!("{err}"); + print_error_chain(err); + 1 + } + }; - terminal::error!("{err}"); - print_error_chain(err); - std::process::exit(1) + std::process::exit(code) } }