aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Davis2024-01-23 18:36:53 +0000
committerBlaž Hrastnik2024-01-24 06:47:49 +0000
commitcb25d13028ec1cdf986a3567ea52562ea654a7b8 (patch)
treea820e7dbceebe37fbfb3897429747ba8bfeb524b
parent6d724a8f331f4b2a8f1a001e990cf6129dc50b00 (diff)
Improve error handling for `which::which` failures
Co-authored-by: Pascal Kuthe <pascalkuthe@pm.me>
-rw-r--r--helix-dap/src/client.rs2
-rw-r--r--helix-dap/src/lib.rs2
-rw-r--r--helix-loader/src/grammar.rs6
-rw-r--r--helix-lsp/src/client.rs2
-rw-r--r--helix-lsp/src/lib.rs2
-rw-r--r--helix-stdx/src/env.rs28
6 files changed, 33 insertions, 9 deletions
diff --git a/helix-dap/src/client.rs b/helix-dap/src/client.rs
index 579811df..18af13ae 100644
--- a/helix-dap/src/client.rs
+++ b/helix-dap/src/client.rs
@@ -113,7 +113,7 @@ impl Client {
id: usize,
) -> Result<(Self, UnboundedReceiver<Payload>)> {
// Resolve path to the binary
- let cmd = helix_stdx::env::which(cmd).map_err(|err| anyhow::anyhow!(err))?;
+ let cmd = helix_stdx::env::which(cmd)?;
let process = Command::new(cmd)
.args(args)
diff --git a/helix-dap/src/lib.rs b/helix-dap/src/lib.rs
index 21162cb8..d0229249 100644
--- a/helix-dap/src/lib.rs
+++ b/helix-dap/src/lib.rs
@@ -19,6 +19,8 @@ pub enum Error {
#[error("server closed the stream")]
StreamClosed,
#[error(transparent)]
+ ExecutableNotFound(#[from] helix_stdx::env::ExecutableNotFoundError),
+ #[error(transparent)]
Other(#[from] anyhow::Error),
}
pub type Result<T> = core::result::Result<T, Error>;
diff --git a/helix-loader/src/grammar.rs b/helix-loader/src/grammar.rs
index 537e1282..7977c6df 100644
--- a/helix-loader/src/grammar.rs
+++ b/helix-loader/src/grammar.rs
@@ -86,10 +86,8 @@ pub fn get_language(name: &str) -> Result<Language> {
}
fn ensure_git_is_available() -> Result<()> {
- match helix_stdx::env::which("git") {
- Ok(_cmd) => Ok(()),
- Err(err) => Err(anyhow::anyhow!("'git' could not be found ({err})")),
- }
+ helix_stdx::env::which("git")?;
+ Ok(())
}
pub fn fetch_grammars() -> Result<()> {
diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs
index f8c2912e..fb32f6eb 100644
--- a/helix-lsp/src/client.rs
+++ b/helix-lsp/src/client.rs
@@ -183,7 +183,7 @@ impl Client {
doc_path: Option<&std::path::PathBuf>,
) -> Result<(Self, UnboundedReceiver<(usize, Call)>, Arc<Notify>)> {
// Resolve path to the binary
- let cmd = helix_stdx::env::which(cmd).map_err(|err| anyhow::anyhow!(err))?;
+ let cmd = helix_stdx::env::which(cmd)?;
let process = Command::new(cmd)
.envs(server_environment)
diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs
index c99ec217..53b2712d 100644
--- a/helix-lsp/src/lib.rs
+++ b/helix-lsp/src/lib.rs
@@ -44,6 +44,8 @@ pub enum Error {
#[error("Unhandled")]
Unhandled,
#[error(transparent)]
+ ExecutableNotFound(#[from] helix_stdx::env::ExecutableNotFoundError),
+ #[error(transparent)]
Other(#[from] anyhow::Error),
}
diff --git a/helix-stdx/src/env.rs b/helix-stdx/src/env.rs
index 3676727f..90a0aee8 100644
--- a/helix-stdx/src/env.rs
+++ b/helix-stdx/src/env.rs
@@ -1,6 +1,5 @@
-pub use which::which;
-
use std::{
+ ffi::OsStr,
path::{Path, PathBuf},
sync::RwLock,
};
@@ -36,10 +35,33 @@ pub fn env_var_is_set(env_var_name: &str) -> bool {
std::env::var_os(env_var_name).is_some()
}
-pub fn binary_exists(binary_name: &str) -> bool {
+pub fn binary_exists<T: AsRef<OsStr>>(binary_name: T) -> bool {
which::which(binary_name).is_ok()
}
+pub fn which<T: AsRef<OsStr>>(
+ binary_name: T,
+) -> Result<std::path::PathBuf, ExecutableNotFoundError> {
+ which::which(binary_name.as_ref()).map_err(|err| ExecutableNotFoundError {
+ command: binary_name.as_ref().to_string_lossy().into_owned(),
+ inner: err,
+ })
+}
+
+#[derive(Debug)]
+pub struct ExecutableNotFoundError {
+ command: String,
+ inner: which::Error,
+}
+
+impl std::fmt::Display for ExecutableNotFoundError {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "command '{}' not found: {}", self.command, self.inner)
+ }
+}
+
+impl std::error::Error for ExecutableNotFoundError {}
+
#[cfg(test)]
mod tests {
use super::{current_working_dir, set_current_working_dir};