diff --git a/src/errors.rs b/src/errors.rs index f1873dc5c..42fe2b5cc 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,9 +1,17 @@ +use eyre::Report; use std::process::ExitStatus; +use crate::toolset::{ToolRequest, ToolSource}; use thiserror::Error; #[derive(Debug, Error)] pub enum Error { + #[error("Failed to resolve {tr} from {ts}: {source:#}")] + FailedToResolveVersion { + tr: ToolRequest, + ts: ToolSource, + source: Report, + }, #[error("[{0}] plugin not installed")] PluginNotInstalled(String), #[error("{0}@{1} not installed")] @@ -20,3 +28,19 @@ fn render_exit_status(exit_status: &Option) -> String { None => "no exit status".into(), } } + +impl Error { + pub fn is_argument_err(err: &Report) -> bool { + err.downcast_ref::() + .map(|e| { + matches!( + e, + Error::FailedToResolveVersion { + ts: ToolSource::Argument, + .. + } + ) + }) + .unwrap_or(false) + } +} diff --git a/src/toolset/builder.rs b/src/toolset/builder.rs index 16ffc7399..e465db2c2 100644 --- a/src/toolset/builder.rs +++ b/src/toolset/builder.rs @@ -5,6 +5,7 @@ use itertools::Itertools; use crate::cli::args::{ForgeArg, ToolArg}; use crate::config::{Config, Settings}; +use crate::errors::Error; use crate::toolset::{ToolRequest, ToolSource, Toolset}; use crate::{config, env}; @@ -60,6 +61,9 @@ impl ToolsetBuilder { self.load_runtime_env(&mut toolset, env::vars().collect())?; self.load_runtime_args(&mut toolset)?; if let Err(err) = toolset.resolve() { + if Error::is_argument_err(&err) { + return Err(err); + } warn!("failed to resolve toolset: {err:#}"); } diff --git a/src/toolset/tool_version_list.rs b/src/toolset/tool_version_list.rs index da7f3442b..ae56d269e 100644 --- a/src/toolset/tool_version_list.rs +++ b/src/toolset/tool_version_list.rs @@ -1,4 +1,5 @@ use crate::cli::args::ForgeArg; +use crate::errors::Error; use crate::forge; use crate::toolset::tool_version_request::ToolRequest; use crate::toolset::{ToolSource, ToolVersion}; @@ -28,8 +29,12 @@ impl ToolVersionList { match tvr.resolve(plugin.as_ref(), latest_versions) { Ok(v) => self.versions.push(v), Err(err) => { - let source = self.source.to_string(); - bail!("failed to resolve version of {plugin} from {source}: {err:#}"); + return Err(Error::FailedToResolveVersion { + tr: tvr.clone(), + ts: self.source.clone(), + source: err, + } + .into()); } } }