From 1afadda81992de15419d867d6eefd490fba56366 Mon Sep 17 00:00:00 2001 From: konsti Date: Mon, 12 May 2025 13:04:41 +0200 Subject: [PATCH] Add more context to errors in high level crates. (#13351) Add error context in some places where it was previously missing, and a few style improvements. --- crates/uv-install-wheel/Cargo.toml | 2 +- crates/uv-installer/src/site_packages.rs | 14 ++++++++++---- crates/uv-python/Cargo.toml | 2 +- crates/uv-requirements-txt/Cargo.toml | 2 +- crates/uv-requirements/src/sources.rs | 12 ++++++++---- crates/uv-trampoline-builder/Cargo.toml | 2 +- crates/uv/src/commands/build_frontend.rs | 7 +++---- crates/uv/src/commands/pip/install.rs | 4 +++- crates/uv/src/commands/pip/sync.rs | 5 +++-- crates/uv/src/commands/project/init.rs | 20 ++++++++++++-------- crates/uv/src/commands/run.rs | 8 +++++--- crates/uv/src/commands/tool/run.rs | 3 ++- 12 files changed, 50 insertions(+), 31 deletions(-) diff --git a/crates/uv-install-wheel/Cargo.toml b/crates/uv-install-wheel/Cargo.toml index b1ea1343e..dd9162e68 100644 --- a/crates/uv-install-wheel/Cargo.toml +++ b/crates/uv-install-wheel/Cargo.toml @@ -55,6 +55,6 @@ same-file = { workspace = true } self-replace = { workspace = true } [dev-dependencies] -anyhow = { version = "1.0.89" } +anyhow = { workspace = true } assert_fs = { version = "1.1.2" } indoc = { workspace = true } diff --git a/crates/uv-installer/src/site_packages.rs b/crates/uv-installer/src/site_packages.rs index d2d0479f8..36257b6fc 100644 --- a/crates/uv-installer/src/site_packages.rs +++ b/crates/uv-installer/src/site_packages.rs @@ -55,10 +55,10 @@ impl SitePackages { for site_packages in interpreter.site_packages() { // Read the site-packages directory. - let site_packages = match fs::read_dir(site_packages) { - Ok(site_packages) => { + let site_packages = match fs::read_dir(site_packages.as_ref()) { + Ok(read_dir) => { // Collect sorted directory paths; `read_dir` is not stable across platforms - let dist_likes: BTreeSet<_> = site_packages + let dist_likes: BTreeSet<_> = read_dir .filter_map(|read_dir| match read_dir { Ok(entry) => match entry.file_type() { Ok(file_type) => (file_type.is_dir() @@ -71,7 +71,13 @@ impl SitePackages { }, Err(err) => Some(Err(err)), }) - .collect::>()?; + .collect::>() + .with_context(|| { + format!( + "Failed to read site-packages directory contents: {}", + site_packages.user_display() + ) + })?; dist_likes } Err(err) if err.kind() == std::io::ErrorKind::NotFound => { diff --git a/crates/uv-python/Cargo.toml b/crates/uv-python/Cargo.toml index 89eb8468b..25317017b 100644 --- a/crates/uv-python/Cargo.toml +++ b/crates/uv-python/Cargo.toml @@ -72,7 +72,7 @@ windows-result = { workspace = true } windows-sys = { workspace = true } [dev-dependencies] -anyhow = { version = "1.0.89" } +anyhow = { workspace = true } assert_fs = { version = "1.1.2" } indoc = { workspace = true } insta = { version = "1.40.0" } diff --git a/crates/uv-requirements-txt/Cargo.toml b/crates/uv-requirements-txt/Cargo.toml index fc6d335e5..617a76123 100644 --- a/crates/uv-requirements-txt/Cargo.toml +++ b/crates/uv-requirements-txt/Cargo.toml @@ -38,7 +38,7 @@ url = { workspace = true } http = ["reqwest", "reqwest-middleware"] [dev-dependencies] -anyhow = { version = "1.0.89" } +anyhow = { workspace = true } assert_fs = { version = "1.1.2" } indoc = { workspace = true } insta = { version = "1.40.0", features = ["filters"] } diff --git a/crates/uv-requirements/src/sources.rs b/crates/uv-requirements/src/sources.rs index c2055c585..abd354bf7 100644 --- a/crates/uv-requirements/src/sources.rs +++ b/crates/uv-requirements/src/sources.rs @@ -170,7 +170,8 @@ impl RequirementsSource { let prompt = format!( "`{name}` looks like a local requirements file but was passed as a package name. Did you mean `-r {name}`?" ); - let confirmation = uv_console::confirm(&prompt, &term, true)?; + let confirmation = + uv_console::confirm(&prompt, &term, true).context("Confirm prompt failed")?; if confirmation { return Self::from_requirements_file(name.into()); } @@ -190,7 +191,8 @@ impl RequirementsSource { let prompt = format!( "`{name}` looks like a local metadata file but was passed as a package name. Did you mean `-r {name}`?" ); - let confirmation = uv_console::confirm(&prompt, &term, true)?; + let confirmation = + uv_console::confirm(&prompt, &term, true).context("Confirm prompt failed")?; if confirmation { return Self::from_requirements_file(name.into()); } @@ -218,7 +220,8 @@ impl RequirementsSource { let prompt = format!( "`{name}` looks like a local requirements file but was passed as a package name. Did you mean `--with-requirements {name}`?" ); - let confirmation = uv_console::confirm(&prompt, &term, true)?; + let confirmation = + uv_console::confirm(&prompt, &term, true).context("Confirm prompt failed")?; if confirmation { return Self::from_requirements_file(name.into()); } @@ -238,7 +241,8 @@ impl RequirementsSource { let prompt = format!( "`{name}` looks like a local metadata file but was passed as a package name. Did you mean `--with-requirements {name}`?" ); - let confirmation = uv_console::confirm(&prompt, &term, true)?; + let confirmation = + uv_console::confirm(&prompt, &term, true).context("Confirm prompt failed")?; if confirmation { return Self::from_requirements_file(name.into()); } diff --git a/crates/uv-trampoline-builder/Cargo.toml b/crates/uv-trampoline-builder/Cargo.toml index a093ce5e9..d5d5436fe 100644 --- a/crates/uv-trampoline-builder/Cargo.toml +++ b/crates/uv-trampoline-builder/Cargo.toml @@ -31,6 +31,6 @@ zip = { workspace = true } [dev-dependencies] assert_cmd = { version = "2.0.16" } assert_fs = { version = "1.1.2" } -anyhow = { version = "1.0.89" } +anyhow = { workspace = true } fs-err = { workspace = true } which = { workspace = true } diff --git a/crates/uv/src/commands/build_frontend.rs b/crates/uv/src/commands/build_frontend.rs index ea7f79fc7..fca41066d 100644 --- a/crates/uv/src/commands/build_frontend.rs +++ b/crates/uv/src/commands/build_frontend.rs @@ -260,8 +260,7 @@ async fn build_impl( let workspace = match workspace { Ok(ref workspace) => workspace, Err(err) => { - return Err(anyhow::Error::from(err) - .context("`--package` was provided, but no workspace was found")); + return Err(err).context("`--package` was provided, but no workspace was found"); } }; @@ -289,8 +288,8 @@ async fn build_impl( let workspace = match workspace { Ok(ref workspace) => workspace, Err(err) => { - return Err(anyhow::Error::from(err) - .context("`--all-packages` was provided, but no workspace was found")); + return Err(err) + .context("`--all-packages` was provided, but no workspace was found"); } }; diff --git a/crates/uv/src/commands/pip/install.rs b/crates/uv/src/commands/pip/install.rs index 0b7157ccf..bef46f6ee 100644 --- a/crates/uv/src/commands/pip/install.rs +++ b/crates/uv/src/commands/pip/install.rs @@ -3,6 +3,7 @@ use std::fmt::Write; use std::path::PathBuf; use std::sync::Arc; +use anyhow::Context; use itertools::Itertools; use owo_colors::OwoColorize; use tracing::{debug, enabled, Level}; @@ -437,7 +438,8 @@ pub(crate) async fn pip_install( let install_path = std::path::absolute(&pylock)?; let install_path = install_path.parent().unwrap(); let content = fs_err::tokio::read_to_string(&pylock).await?; - let lock = toml::from_str::(&content)?; + let lock = toml::from_str::(&content) + .with_context(|| format!("Not a valid pylock.toml file: {}", pylock.user_display()))?; let resolution = lock.to_resolution(install_path, marker_env.markers(), &tags, &build_options)?; diff --git a/crates/uv/src/commands/pip/sync.rs b/crates/uv/src/commands/pip/sync.rs index ad4f74b1f..6d8d4005b 100644 --- a/crates/uv/src/commands/pip/sync.rs +++ b/crates/uv/src/commands/pip/sync.rs @@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet}; use std::fmt::Write; use std::sync::Arc; -use anyhow::Result; +use anyhow::{Context, Result}; use owo_colors::OwoColorize; use tracing::debug; @@ -372,7 +372,8 @@ pub(crate) async fn pip_sync( let install_path = std::path::absolute(&pylock)?; let install_path = install_path.parent().unwrap(); let content = fs_err::tokio::read_to_string(&pylock).await?; - let lock = toml::from_str::(&content)?; + let lock = toml::from_str::(&content) + .with_context(|| format!("Not a valid pylock.toml file: {}", pylock.user_display()))?; let resolution = lock.to_resolution(install_path, marker_env.markers(), &tags, &build_options)?; diff --git a/crates/uv/src/commands/project/init.rs b/crates/uv/src/commands/project/init.rs index bd16549f4..89f43723a 100644 --- a/crates/uv/src/commands/project/init.rs +++ b/crates/uv/src/commands/project/init.rs @@ -236,10 +236,12 @@ async fn init_script( } Err(err) if err.kind() == std::io::ErrorKind::NotFound => None, Err(err) => { - return Err(anyhow::Error::from(err).context(format!( - "Failed to read script at `{}`", - script_path.simplified_display().cyan() - ))); + return Err(err).with_context(|| { + format!( + "Failed to read script at `{}`", + script_path.simplified_display().cyan() + ) + }); } }; @@ -328,10 +330,12 @@ async fn init_project( warn!("Ignoring workspace discovery error due to `--no-workspace`: {err}"); None } else { - return Err(anyhow::Error::from(err).context(format!( - "Failed to discover parent workspace; use `{}` to ignore", - "uv init --no-workspace".green() - ))); + return Err(err).with_context(|| { + format!( + "Failed to discover parent workspace; use `{}` to ignore", + "uv init --no-workspace".green() + ) + }); } } } diff --git a/crates/uv/src/commands/run.rs b/crates/uv/src/commands/run.rs index 75f7bc3f2..ddbd2bb02 100644 --- a/crates/uv/src/commands/run.rs +++ b/crates/uv/src/commands/run.rs @@ -1,7 +1,8 @@ -use crate::commands::ExitStatus; use tokio::process::Child; use tracing::debug; +use crate::commands::ExitStatus; + /// Wait for the child process to complete, handling signals and error codes. /// /// Note that this registers handles to ignore some signals in the parent process. This is safe as @@ -39,6 +40,7 @@ pub(crate) async fn run_to_completion(mut handle: Child) -> anyhow::Result anyhow::Result anyhow::Result