This commit is contained in:
konstin 2025-05-08 17:58:11 +02:00
parent 9717fb58af
commit 77055f0c9d
143 changed files with 584 additions and 178 deletions

107
Cargo.lock generated
View file

@ -88,6 +88,13 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "anyhow"
version = "0.1.0"
dependencies = [
"anyhow 1.0.98",
]
[[package]]
name = "anyhow"
version = "1.0.98"
@ -509,7 +516,7 @@ version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "527f6e2a4e80492e90628052be879a5996c2453ad5ec745bfa310a80b7eca20a"
dependencies = [
"anyhow",
"anyhow 1.0.98",
"core-foundation",
"filetime",
"hex",
@ -3113,7 +3120,7 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57f17d28a6e6acfe1733fe24bcd30774d13bffa4b8a22535b4c8c98423088d4e"
dependencies = [
"anyhow",
"anyhow 1.0.98",
"async-trait",
"http",
"reqwest",
@ -3128,7 +3135,7 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29c73e4195a6bfbcb174b790d9b3407ab90646976c55de58a6515da25d851178"
dependencies = [
"anyhow",
"anyhow 1.0.98",
"async-trait",
"futures",
"getrandom 0.2.15",
@ -4297,7 +4304,7 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "382e025ef8e0db646343dd2cf56af9d7fe6f5eabce5f388f8e5ec7234f555a0f"
dependencies = [
"anyhow",
"anyhow 1.0.98",
"fs-err 2.11.0",
"itertools 0.13.0",
"once_cell",
@ -4384,6 +4391,22 @@ dependencies = [
"tracing-subscriber",
]
[[package]]
name = "traversable-derive"
version = "0.1.0"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "traversable-error"
version = "0.1.0"
dependencies = [
"anyhow 0.1.0",
"traversable-derive",
]
[[package]]
name = "try-lock"
version = "0.2.5"
@ -4575,7 +4598,7 @@ name = "uv"
version = "0.7.2"
dependencies = [
"anstream",
"anyhow",
"anyhow 0.1.0",
"assert_cmd",
"assert_fs",
"axoupdater",
@ -4621,6 +4644,7 @@ dependencies = [
"tracing-durations-export",
"tracing-subscriber",
"tracing-tree",
"traversable-error",
"unicode-width 0.2.0",
"url",
"uv-auth",
@ -4678,7 +4702,7 @@ dependencies = [
name = "uv-auth"
version = "0.0.1"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"async-trait",
"base64 0.22.1",
"futures",
@ -4708,7 +4732,7 @@ dependencies = [
name = "uv-bench"
version = "0.0.0"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"codspeed-criterion-compat",
"criterion",
"jiff",
@ -4736,7 +4760,7 @@ dependencies = [
name = "uv-build"
version = "0.7.2"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"uv-build-backend",
"uv-version",
]
@ -4761,6 +4785,7 @@ dependencies = [
"thiserror 2.0.12",
"toml",
"tracing",
"traversable-error",
"uv-distribution-filename",
"uv-fs",
"uv-globfilter",
@ -4797,6 +4822,7 @@ dependencies = [
"tokio",
"toml_edit",
"tracing",
"traversable-error",
"uv-configuration",
"uv-distribution",
"uv-distribution-types",
@ -4849,6 +4875,7 @@ dependencies = [
"thiserror 2.0.12",
"toml",
"tracing",
"traversable-error",
"walkdir",
]
@ -4868,7 +4895,7 @@ name = "uv-cli"
version = "0.0.1"
dependencies = [
"anstream",
"anyhow",
"anyhow 0.1.0",
"clap",
"clap_complete_command",
"fs-err 3.1.0",
@ -4895,7 +4922,7 @@ dependencies = [
name = "uv-client"
version = "0.0.1"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"async-trait",
"async_http_range_reader",
"async_zip",
@ -4925,6 +4952,7 @@ dependencies = [
"tokio",
"tokio-util",
"tracing",
"traversable-error",
"url",
"uv-auth",
"uv-cache",
@ -4950,7 +4978,7 @@ dependencies = [
name = "uv-configuration"
version = "0.0.1"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"clap",
"either",
"fs-err 3.1.0",
@ -4963,6 +4991,7 @@ dependencies = [
"serde_json",
"thiserror 2.0.12",
"tracing",
"traversable-error",
"url",
"uv-auth",
"uv-cache",
@ -4989,7 +5018,7 @@ name = "uv-dev"
version = "0.0.1"
dependencies = [
"anstream",
"anyhow",
"anyhow 0.1.0",
"clap",
"fs-err 3.1.0",
"itertools 0.14.0",
@ -5043,13 +5072,14 @@ dependencies = [
name = "uv-dispatch"
version = "0.0.1"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"futures",
"itertools 0.14.0",
"rustc-hash",
"thiserror 2.0.12",
"tokio",
"tracing",
"traversable-error",
"uv-build-backend",
"uv-build-frontend",
"uv-cache",
@ -5074,7 +5104,7 @@ dependencies = [
name = "uv-distribution"
version = "0.0.1"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"either",
"fs-err 3.1.0",
"futures",
@ -5093,6 +5123,7 @@ dependencies = [
"tokio-util",
"toml",
"tracing",
"traversable-error",
"url",
"uv-cache",
"uv-cache-info",
@ -5127,6 +5158,7 @@ dependencies = [
"serde",
"smallvec",
"thiserror 2.0.12",
"traversable-error",
"url",
"uv-cache-key",
"uv-normalize",
@ -5156,6 +5188,7 @@ dependencies = [
"thiserror 2.0.12",
"toml",
"tracing",
"traversable-error",
"url",
"uv-auth",
"uv-cache-info",
@ -5191,6 +5224,7 @@ dependencies = [
"tokio",
"tokio-util",
"tracing",
"traversable-error",
"uv-configuration",
"uv-distribution-filename",
"uv-pypi-types",
@ -5225,7 +5259,8 @@ dependencies = [
name = "uv-git"
version = "0.0.1"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"anyhow 1.0.98",
"cargo-util",
"dashmap",
"fs-err 3.1.0",
@ -5234,6 +5269,7 @@ dependencies = [
"thiserror 2.0.12",
"tokio",
"tracing",
"traversable-error",
"url",
"uv-auth",
"uv-cache-key",
@ -5251,6 +5287,7 @@ dependencies = [
"serde",
"thiserror 2.0.12",
"tracing",
"traversable-error",
"url",
]
@ -5268,6 +5305,7 @@ dependencies = [
"tempfile",
"thiserror 2.0.12",
"tracing",
"traversable-error",
"walkdir",
]
@ -5275,7 +5313,7 @@ dependencies = [
name = "uv-install-wheel"
version = "0.0.1"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"assert_fs",
"clap",
"configparser",
@ -5297,6 +5335,7 @@ dependencies = [
"tempfile",
"thiserror 2.0.12",
"tracing",
"traversable-error",
"uv-cache-info",
"uv-distribution-filename",
"uv-fs",
@ -5313,7 +5352,7 @@ dependencies = [
name = "uv-installer"
version = "0.0.1"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"async-channel",
"fs-err 3.1.0",
"futures",
@ -5324,6 +5363,7 @@ dependencies = [
"thiserror 2.0.12",
"tokio",
"tracing",
"traversable-error",
"url",
"uv-cache",
"uv-cache-info",
@ -5367,6 +5407,7 @@ dependencies = [
"tokio",
"tokio-util",
"tracing",
"traversable-error",
"uv-distribution-filename",
"uv-normalize",
"uv-pypi-types",
@ -5430,6 +5471,7 @@ dependencies = [
"thiserror 2.0.12",
"tracing",
"tracing-test",
"traversable-error",
"unicode-width 0.2.0",
"url",
"uv-fs",
@ -5456,6 +5498,7 @@ dependencies = [
"rustc-hash",
"serde",
"thiserror 2.0.12",
"traversable-error",
"uv-small-str",
]
@ -5481,6 +5524,7 @@ dependencies = [
"tokio",
"tokio-util",
"tracing",
"traversable-error",
"url",
"uv-auth",
"uv-cache",
@ -5500,7 +5544,7 @@ dependencies = [
name = "uv-pypi-types"
version = "0.0.1"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"hashbrown 0.15.3",
"indexmap",
"insta",
@ -5517,6 +5561,7 @@ dependencies = [
"thiserror 2.0.12",
"toml_edit",
"tracing",
"traversable-error",
"url",
"uv-distribution-filename",
"uv-git-types",
@ -5530,7 +5575,7 @@ dependencies = [
name = "uv-python"
version = "0.0.1"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"assert_fs",
"clap",
"configparser",
@ -5562,6 +5607,7 @@ dependencies = [
"tokio",
"tokio-util",
"tracing",
"traversable-error",
"url",
"uv-cache",
"uv-cache-info",
@ -5590,7 +5636,7 @@ dependencies = [
name = "uv-requirements"
version = "0.1.0"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"configparser",
"console",
"fs-err 3.1.0",
@ -5600,6 +5646,7 @@ dependencies = [
"thiserror 2.0.12",
"toml",
"tracing",
"traversable-error",
"url",
"uv-cache-key",
"uv-client",
@ -5624,7 +5671,7 @@ dependencies = [
name = "uv-requirements-txt"
version = "0.0.1"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"assert_fs",
"fs-err 3.1.0",
"indoc",
@ -5639,6 +5686,7 @@ dependencies = [
"thiserror 2.0.12",
"tokio",
"tracing",
"traversable-error",
"unscanny",
"url",
"uv-client",
@ -5681,6 +5729,7 @@ dependencies = [
"toml",
"toml_edit",
"tracing",
"traversable-error",
"url",
"uv-cache-key",
"uv-client",
@ -5718,6 +5767,7 @@ dependencies = [
"serde",
"thiserror 2.0.12",
"toml",
"traversable-error",
"url",
"uv-pep440",
"uv-pep508",
@ -5738,6 +5788,7 @@ dependencies = [
"thiserror 2.0.12",
"toml",
"tracing",
"traversable-error",
"url",
"uv-cache-info",
"uv-configuration",
@ -5761,7 +5812,7 @@ dependencies = [
name = "uv-shell"
version = "0.0.1"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"home",
"same-file",
"tracing",
@ -5810,6 +5861,7 @@ dependencies = [
"toml",
"toml_edit",
"tracing",
"traversable-error",
"uv-cache",
"uv-dirs",
"uv-distribution-types",
@ -5837,6 +5889,7 @@ dependencies = [
"serde",
"thiserror 2.0.12",
"tracing",
"traversable-error",
"url",
"uv-distribution-types",
"uv-normalize",
@ -5849,11 +5902,12 @@ dependencies = [
name = "uv-trampoline-builder"
version = "0.0.1"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"assert_cmd",
"assert_fs",
"fs-err 3.1.0",
"thiserror 2.0.12",
"traversable-error",
"uv-fs",
"which",
"zip",
@ -5863,9 +5917,10 @@ dependencies = [
name = "uv-types"
version = "0.0.1"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"rustc-hash",
"thiserror 2.0.12",
"traversable-error",
"url",
"uv-cache",
"uv-configuration",
@ -5895,6 +5950,7 @@ dependencies = [
"self-replace",
"thiserror 2.0.12",
"tracing",
"traversable-error",
"uv-fs",
"uv-pypi-types",
"uv-python",
@ -5915,7 +5971,7 @@ dependencies = [
name = "uv-workspace"
version = "0.0.1"
dependencies = [
"anyhow",
"anyhow 0.1.0",
"assert_fs",
"fs-err 3.1.0",
"glob",
@ -5932,6 +5988,7 @@ dependencies = [
"toml",
"toml_edit",
"tracing",
"traversable-error",
"url",
"uv-build-backend",
"uv-cache-key",

View file

@ -20,6 +20,8 @@ authors = ["uv"]
license = "MIT OR Apache-2.0"
[workspace.dependencies]
traversable-error = { path = "crates/traversable-error" }
traversable-derive = { path = "crates/traversable-derive" }
uv-auth = { path = "crates/uv-auth" }
uv-build-backend = { path = "crates/uv-build-backend" }
uv-build-frontend = { path = "crates/uv-build-frontend" }
@ -72,7 +74,8 @@ uv-warnings = { path = "crates/uv-warnings" }
uv-workspace = { path = "crates/uv-workspace" }
anstream = { version = "0.6.15" }
anyhow = { version = "1.0.89" }
anyhow = { path = "crates/anyhow-wrapper" }
anyhow-original = { package = "anyhow", version = "1.0.89" }
arcstr = { version = "1.2.0" }
astral-tokio-tar = { version = "0.5.1" }
async-channel = { version = "2.3.1" }

View file

@ -0,0 +1,16 @@
[package]
name = "anyhow"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true
homepage.workspace = true
documentation.workspace = true
repository.workspace = true
authors.workspace = true
license.workspace = true
[dependencies]
anyhow-original = { workspace = true }
[lints]
workspace = true

View file

@ -0,0 +1,174 @@
// macro pass-through
pub use anyhow_original;
use std::convert::Infallible;
#[macro_export]
macro_rules! anyhow {
($($args:tt)*) => {
$crate::Error::Anyhow($crate::anyhow_original::anyhow!($($args)*))
};
}
#[macro_export]
macro_rules! format_err {
($($args:tt)*) => {
$crate::Error::Anyhow($crate::anyhow_original::format_err!($($args)*))
};
}
#[macro_export]
macro_rules! bail {
($msg:literal $(,)?) => {
return $crate::anyhow_original::__private::Err($crate::anyhow!($msg))
};
($err:expr $(,)?) => {
return $crate::anyhow_original::__private::Err($crate::anyhow!($err))
};
($fmt:expr, $($arg:tt)*) => {
return $crate::anyhow_original::__private::Err($crate::anyhow!($fmt, $($arg)*))
};
}
/// Copied almost verbatim from anyhow
pub trait Context<T, E> {
/// Wrap the error value with additional context.
fn context<C>(self, context: C) -> anyhow_original::Result<T, Error>
where
C: std::fmt::Display + Send + Sync + 'static;
/// Wrap the error value with additional context that is evaluated lazily
/// only once an error does occur.
fn with_context<C, F>(self, f: F) -> anyhow_original::Result<T, Error>
where
C: std::fmt::Display + Send + Sync + 'static,
F: FnOnce() -> C;
}
impl<T, E> Context<T, E> for std::result::Result<T, E>
where
E: std::error::Error + Send + Sync + 'static,
{
fn context<C>(self, context: C) -> std::result::Result<T, Error>
where
C: std::fmt::Display + Send + Sync + 'static,
{
Ok(anyhow_original::Context::context(self, context)?)
}
fn with_context<C, F>(self, context: F) -> std::result::Result<T, Error>
where
C: std::fmt::Display + Send + Sync + 'static,
F: FnOnce() -> C,
{
Ok(anyhow_original::Context::with_context(self, context)?)
}
}
impl<T> Context<T, Infallible> for Option<T> {
fn context<C>(self, context: C) -> std::result::Result<T, Error>
where
C: std::fmt::Display + Send + Sync + 'static,
{
Ok(anyhow_original::Context::context(self, context)?)
}
fn with_context<C, F>(self, context: F) -> std::result::Result<T, Error>
where
C: std::fmt::Display + Send + Sync + 'static,
F: FnOnce() -> C,
{
Ok(anyhow_original::Context::with_context(self, context)?)
}
}
pub type Result<T, E = Error> = std::result::Result<T, E>;
pub trait TraversableError: std::error::Error + Send + Sync + 'static {
fn name(&self) -> &str;
}
pub enum Error {
Traversable(Box<dyn TraversableError>),
Anyhow(anyhow_original::Error),
}
impl Error {
pub fn new<E>(error: E) -> Self
where
E: std::error::Error + Send + Sync + 'static,
{
Self::Anyhow(anyhow_original::Error::new(error))
}
pub fn chain(&self) -> anyhow_original::Chain {
match self {
Error::Traversable(err) => anyhow_original::Chain::new(err.as_ref()),
Error::Anyhow(err) => err.chain(),
}
}
}
impl std::fmt::Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Traversable(err) => std::fmt::Debug::fmt(err, f),
Self::Anyhow(err) => std::fmt::Debug::fmt(err, f),
}
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Traversable(err) => std::fmt::Display::fmt(err, f),
Self::Anyhow(err) => std::fmt::Display::fmt(err, f),
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Traversable(err) => Some(err.as_ref()),
Self::Anyhow(err) => Some(err.as_ref()),
}
}
}
impl<E: TraversableError> From<E> for Error {
fn from(error: E) -> Self {
Self::Traversable(Box::new(error))
}
}
impl<E: TraversableError> TraversableError for Box<E> {
fn name(&self) -> &str {
(&**self).name()
}
}
impl TraversableError for std::fmt::Error {
fn name(&self) -> &str {
"std::fmt::Error"
}
}
impl TraversableError for std::io::Error {
fn name(&self) -> &str {
"std::io::Error"
}
}
// TODO(konsti): Where are the matching std and anyhow methods?
// anyhow supports `GIT.as_ref()?` but our error doesn't.
impl<E: TraversableError> TraversableError for &'static E {
fn name(&self) -> &str {
TraversableError::name(*self)
}
}
impl From<anyhow_original::Error> for Error {
fn from(error: anyhow_original::Error) -> Self {
Self::Anyhow(error)
}
}

View file

@ -0,0 +1,20 @@
[package]
name = "traversable-derive"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true
homepage.workspace = true
documentation.workspace = true
repository.workspace = true
authors.workspace = true
license.workspace = true
[lib]
proc-macro = true
[dependencies]
quote = { workspace = true }
syn = { workspace = true }
[lints]
workspace = true

View file

@ -0,0 +1,51 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Data, DeriveInput, Fields};
#[proc_macro_derive(TraversableError)]
pub fn derive_traversable_error(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let name = input.ident;
let name_impl = match input.data {
Data::Enum(ref enum_data) => {
let match_arms = enum_data.variants.iter().map(|variant| {
let variant_name = &variant.ident;
let field_pattern = match &variant.fields {
Fields::Named(_) => quote! { { .. } },
Fields::Unnamed(_) => quote! { (..) },
Fields::Unit => quote! {},
};
quote! {
#name::#variant_name #field_pattern => {
concat!(stringify!(#name), "::", stringify!(#variant_name))
}
}
});
quote! {
fn name(&self) -> &str {
match self {
#(#match_arms,)*
}
}
}
}
_ => {
quote! {
fn name(&self) -> &str {
stringify!(#name)
}
}
}
};
let expanded = quote! {
impl ::traversable_error::anyhow::TraversableError for #name {
#name_impl
}
};
expanded.into()
}

View file

@ -0,0 +1,19 @@
[package]
name = "traversable-error"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true
homepage.workspace = true
documentation.workspace = true
repository.workspace = true
authors.workspace = true
license.workspace = true
[lib]
[dependencies]
anyhow = { workspace = true}
traversable-derive = { workspace = true}
[lints]
workspace = true

View file

@ -243,10 +243,13 @@ impl Middleware for AuthMiddleware {
// <https://github.com/TrueLayer/reqwest-middleware/blob/abdf1844c37092d323683c2396b7eefda1418d3c/reqwest-retry/src/middleware.rs#L141-L149>
// Clone the request so we can retry it on authentication failure
let retry_request = request.try_clone().ok_or_else(|| {
Error::Middleware(anyhow!(
"Request object is not cloneable. Are you passing a streaming body?"
.to_string()
))
Error::Middleware(
anyhow!(
"Request object is not cloneable. Are you passing a streaming body?"
.to_string()
)
.into(),
)
})?;
let response = next.clone().run(request, extensions).await?;
@ -336,9 +339,9 @@ impl Middleware for AuthMiddleware {
if let Some(response) = response {
Ok(response)
} else {
Err(Error::Middleware(format_err!(
"Missing credentials for {url}"
)))
Err(Error::Middleware(
format_err!("Missing credentials for {url}").into(),
))
}
}
}
@ -361,7 +364,9 @@ impl AuthMiddleware {
};
let url = request.url().clone();
if matches!(auth_policy, AuthPolicy::Always) && credentials.password().is_none() {
return Err(Error::Middleware(format_err!("Missing password for {url}")));
return Err(Error::Middleware(
format_err!("Missing password for {url}").into(),
));
}
let result = next.run(request, extensions).await;

View file

@ -37,6 +37,7 @@ sha2 = { workspace = true }
spdx = { workspace = true }
tar = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
toml = { workspace = true }
tracing = { workspace = true }
version-ranges = { workspace = true }

View file

@ -24,7 +24,7 @@ use uv_pypi_types::{Identifier, IdentifierParseError};
use crate::metadata::ValidationError;
#[derive(Debug, Error)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum Error {
#[error(transparent)]
Io(#[from] io::Error),

View file

@ -26,7 +26,7 @@ use crate::{BuildBackendSettings, Error};
/// By default, we ignore generated python files.
pub(crate) const DEFAULT_EXCLUDES: &[&str] = &["__pycache__", "*.pyc", "*.pyo"];
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum ValidationError {
/// The spec isn't clear about what the values in that field would be, and we only support the
/// default value (UTF-8).

View file

@ -41,6 +41,7 @@ serde = { workspace = true }
serde_json = { workspace = true }
tempfile = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tokio = { workspace = true }
toml_edit = { workspace = true }
tracing = { workspace = true }

View file

@ -54,7 +54,7 @@ static TORCH_NOT_FOUND_RE: LazyLock<Regex> =
static DISTUTILS_NOT_FOUND_RE: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"ModuleNotFoundError: No module named 'distutils'").unwrap());
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum Error {
#[error(transparent)]
Io(#[from] io::Error),
@ -120,7 +120,7 @@ enum MissingLibrary {
DeprecatedModule(String, Version),
}
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub struct MissingHeaderCause {
missing_library: MissingLibrary,
package_name: Option<PackageName>,
@ -248,7 +248,7 @@ impl Display for MissingHeaderCause {
}
}
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub struct BuildBackendError {
message: String,
exit_code: ExitStatus,
@ -287,7 +287,7 @@ impl Display for BuildBackendError {
}
}
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub struct MissingHeaderError {
message: String,
exit_code: ExitStatus,

View file

@ -21,6 +21,7 @@ globwalk = { workspace = true }
schemars = { workspace = true, optional = true }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
traversable-error = { workspace = true }
toml = { workspace = true }
tracing = { workspace = true }
walkdir = { workspace = true }

View file

@ -9,7 +9,7 @@ use tracing::{debug, warn};
use crate::git_info::{Commit, Tags};
use crate::timestamp::Timestamp;
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
pub enum CacheInfoError {
#[error("Failed to parse glob patterns for `cache-keys`: {0}")]
Glob(#[from] globwalk::GlobError),

View file

@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};
use tracing::warn;
use walkdir::WalkDir;
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
pub(crate) enum GitInfoError {
#[error("The repository at {0} is missing a `.git` directory")]
MissingGitDir(PathBuf),

View file

@ -51,6 +51,7 @@ serde = { workspace = true }
serde_json = { workspace = true }
sys-info = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tl = { workspace = true }
tokio = { workspace = true }
tokio-util = { workspace = true }

View file

@ -11,7 +11,7 @@ use uv_normalize::PackageName;
use crate::middleware::OfflineError;
use crate::{html, FlatIndexError};
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
#[error(transparent)]
pub struct Error {
kind: Box<ErrorKind>,
@ -147,7 +147,7 @@ impl From<ErrorKind> for Error {
}
}
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
pub enum ErrorKind {
#[error(transparent)]
InvalidUrl(#[from] uv_distribution_types::ToUrlError),

View file

@ -16,7 +16,7 @@ use crate::cached_client::{CacheControl, CachedClientError};
use crate::html::SimpleHtml;
use crate::{CachedClient, Connectivity, Error, ErrorKind, OwnedArchive};
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
pub enum FlatIndexError {
#[error("Expected a file URL, but received: {0}")]
NonFileUrl(Url),
@ -28,7 +28,7 @@ pub enum FlatIndexError {
FindLinksUrl(Url, #[source] Error),
}
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
pub enum FindLinksDirectoryError {
#[error(transparent)]
Io(#[from] std::io::Error),

View file

@ -224,7 +224,7 @@ impl SimpleHtml {
}
}
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
pub enum Error {
#[error(transparent)]
Utf8(#[from] std::str::Utf8Error),

View file

@ -2,7 +2,7 @@ use reqwest::Identity;
use std::ffi::OsStr;
use std::io::Read;
#[derive(thiserror::Error, Debug)]
#[derive(traversable_error::TraversableError, thiserror::Error, Debug)]
pub(crate) enum CertificateError {
#[error(transparent)]
Io(#[from] std::io::Error),

View file

@ -39,6 +39,7 @@ serde = { workspace = true }
serde-untagged = { workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tracing = { workspace = true }
url = { workspace = true }

View file

@ -73,7 +73,7 @@ impl serde::Serialize for TrustedHost {
}
}
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
pub enum TrustedHostError {
#[error("missing host for `--trusted-host`: `{0}`")]
MissingHost(String),

View file

@ -5,7 +5,7 @@ use std::process::{Command, Stdio};
use serde::Deserialize;
use uv_git::GIT;
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
pub enum VersionControlError {
#[error("Attempted to initialize a Git repository, but `git` was not found in PATH")]
GitNotInstalled,

View file

@ -41,5 +41,6 @@ futures = { workspace = true }
itertools = { workspace = true }
rustc-hash = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }

View file

@ -40,7 +40,7 @@ use uv_types::{
};
use uv_workspace::WorkspaceCache;
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum BuildDispatchError {
#[error(transparent)]
BuildFrontend(#[from] AnyErrorBuild),

View file

@ -27,6 +27,7 @@ rkyv = { workspace = true, features = ["smallvec-1"] }
serde = { workspace = true }
smallvec = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
url = { workspace = true }
[dev-dependencies]

View file

@ -3,7 +3,7 @@ use std::str::FromStr;
use uv_small_str::SmallString;
#[derive(thiserror::Error, Debug)]
#[derive(traversable_error::TraversableError, thiserror::Error, Debug)]
pub enum BuildTagError {
#[error("must not be empty")]
Empty,

View file

@ -5,7 +5,7 @@ use thiserror::Error;
use uv_normalize::{InvalidNameError, PackageName};
use uv_pep440::{Version, VersionParseError};
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum EggInfoFilenameError {
#[error("The filename \"{0}\" does not end in `.egg-info`")]
InvalidExtension(String),

View file

@ -104,7 +104,7 @@ impl Display for SourceDistExtension {
}
}
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum ExtensionError {
#[error("`.whl`, `.tar.gz`, `.zip`, `.tar.bz2`, `.tar.lz`, `.tar.lzma`, `.tar.xz`, `.tar.zst`, `.tar`, `.tbz`, `.tgz`, `.tlz`, or `.txz`")]
Dist,

View file

@ -141,7 +141,7 @@ impl Display for SourceDistFilename {
}
}
#[derive(Error, traversable_error::TraversableError, Debug, Clone)]
#[derive(traversable_error::TraversableError, Error, Debug, Clone)]
pub struct SourceDistFilenameError {
filename: String,
kind: SourceDistFilenameErrorKind,
@ -157,7 +157,7 @@ impl Display for SourceDistFilenameError {
}
}
#[derive(Error, traversable_error::TraversableError, Debug, Clone)]
#[derive(traversable_error::TraversableError, Error, Debug, Clone)]
enum SourceDistFilenameErrorKind {
#[error("Name doesn't start with package name {0}")]
Filename(PackageName),

View file

@ -355,7 +355,7 @@ impl Serialize for WheelFilename {
}
}
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum WheelFilenameError {
#[error("The wheel filename \"{0}\" is invalid: {1}")]
InvalidWheelFileName(String, String),

View file

@ -44,6 +44,7 @@ schemars = { workspace = true, optional = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tracing = { workspace = true }
url = { workspace = true }
version-ranges = { workspace = true }

View file

@ -2,7 +2,7 @@ use url::Url;
use uv_normalize::PackageName;
#[derive(thiserror::Error, Debug)]
#[derive(traversable_error::TraversableError, thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Io(#[from] std::io::Error),

View file

@ -11,7 +11,7 @@ use uv_pypi_types::{CoreMetadata, HashDigests, Yanked};
use uv_small_str::SmallString;
/// Error converting [`uv_pypi_types::File`] to [`distribution_type::File`].
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
pub enum FileConversionError {
#[error("Failed to parse `requires-python`: `{0}`")]
RequiresPython(String, #[source] VersionSpecifiersParseError),
@ -197,7 +197,7 @@ impl Display for UrlString {
}
/// An error that occurs when a [`FileLocation`] is not a valid URL.
#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
#[derive(Clone, Debug, Eq, PartialEq, traversable_error::TraversableError, thiserror::Error)]
pub enum ToUrlError {
/// An error that occurs when the base URL in [`FileLocation::Relative`]
/// could not be parsed as a valid URL.

View file

@ -375,7 +375,7 @@ impl<'a> From<&'a IndexUrl> for IndexMetadataRef<'a> {
}
/// An error that can occur when parsing an [`Index`].
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum IndexSourceError {
#[error(transparent)]
Url(#[from] IndexUrlError),

View file

@ -87,7 +87,7 @@ impl Deref for IndexName {
}
/// An error that can occur when parsing an [`IndexName`].
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum IndexNameError {
#[error("Index included a name, but the name was empty")]
EmptyName,

View file

@ -160,7 +160,7 @@ impl Verbatim for IndexUrl {
}
/// An error that can occur when parsing an [`IndexUrl`].
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum IndexUrlError {
#[error(transparent)]
Io(#[from] std::io::Error),

View file

@ -17,7 +17,7 @@ use uv_pypi_types::{DirectUrl, MetadataError};
use crate::{DistributionMetadata, InstalledMetadata, InstalledVersion, Name, VersionOrUrlRef};
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum InstalledDistError {
#[error(transparent)]
Io(#[from] std::io::Error),

View file

@ -22,7 +22,7 @@ use uv_pypi_types::{
ParsedUrl, ParsedUrlError, VerbatimParsedUrl,
};
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum RequirementError {
#[error(transparent)]
VerbatimUrlError(#[from] uv_pep508::VerbatimUrlError),

View file

@ -49,6 +49,7 @@ rustc-hash = { workspace = true }
serde = { workspace = true, features = ["derive"] }
tempfile = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tokio = { workspace = true }
tokio-util = { workspace = true, features = ["compat"] }
toml = { workspace = true }

View file

@ -15,7 +15,7 @@ use uv_pep440::{Version, VersionSpecifiers};
use uv_pypi_types::{HashAlgorithm, HashDigest};
use uv_types::AnyErrorBuild;
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
pub enum Error {
#[error("Building source distributions is disabled")]
NoBuild,
@ -162,7 +162,9 @@ impl From<reqwest::Error> for Error {
impl From<reqwest_middleware::Error> for Error {
fn from(error: reqwest_middleware::Error) -> Self {
match error {
reqwest_middleware::Error::Middleware(error) => Self::ReqwestMiddlewareError(error),
reqwest_middleware::Error::Middleware(error) => {
Self::ReqwestMiddlewareError(error.into())
}
reqwest_middleware::Error::Reqwest(error) => {
Self::Reqwest(WrappedReqwestError::from(error))
}

View file

@ -502,7 +502,7 @@ impl LoweredRequirement {
/// An error parsing and merging `tool.uv.sources` with
/// `project.{dependencies,optional-dependencies}`.
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum LoweringError {
#[error("`{0}` is included as a workspace member, but is missing an entry in `tool.uv.sources` (e.g., `{0} = {{ workspace = true }}`)")]
MissingWorkspaceSource(PackageName),

View file

@ -20,7 +20,7 @@ mod build_requires;
mod lowering;
mod requires_dist;
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum MetadataError {
#[error(transparent)]
Workspace(#[from] WorkspaceError),

View file

@ -32,6 +32,7 @@ reqwest = { workspace = true }
rustc-hash = { workspace = true }
sha2 = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tokio = { workspace = true }
tokio-util = { workspace = true, features = ["compat"] }
tracing = { workspace = true }

View file

@ -1,6 +1,6 @@
use std::{ffi::OsString, path::PathBuf};
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
pub enum Error {
#[error(transparent)]
Zip(#[from] zip::result::ZipError),

View file

@ -18,5 +18,6 @@ workspace = true
[dependencies]
serde = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tracing = { workspace = true }
url = { workspace = true }

View file

@ -9,7 +9,7 @@ mod github;
mod oid;
mod reference;
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum GitUrlParseError {
#[error(
"Unsupported Git URL scheme `{0}:` in `{1}` (expected one of `https:`, `ssh:`, or `file:`)"

View file

@ -24,7 +24,7 @@ impl GitOid {
}
}
#[derive(Debug, Error, traversable_error::TraversableError, PartialEq)]
#[derive(Debug, traversable_error::TraversableError, Error, PartialEq)]
pub enum OidParseError {
#[error("Object ID can be at most 40 hex characters")]
TooLong,

View file

@ -24,12 +24,14 @@ uv-static = { workspace = true }
uv-version = { workspace = true }
anyhow = { workspace = true }
anyhow_original = { package = "anyhow", version = "1" }
cargo-util = { workspace = true }
dashmap = { workspace = true }
fs-err = { workspace = true, features = ["tokio"] }
reqwest = { workspace = true, features = ["blocking"] }
reqwest-middleware = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
url = { workspace = true }

View file

@ -7,7 +7,7 @@ use std::path::{Path, PathBuf};
use std::str::{self};
use std::sync::LazyLock;
use anyhow::{Context, Result};
use anyhow_original::{Context, Result};
use cargo_util::{paths, ProcessBuilder};
use reqwest::StatusCode;
use reqwest_middleware::ClientWithMiddleware;
@ -23,7 +23,7 @@ use uv_version::version;
/// checkout is ready to go. See [`GitCheckout::reset`] for why we need this.
const CHECKOUT_READY_LOCK: &str = ".ok";
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
pub enum GitError {
#[error("Git executable not found. Ensure that Git is installed and available.")]
GitNotFound,
@ -97,7 +97,7 @@ impl ReferenceOrOid<'_> {
Self::Oid(s) => repo.rev_parse(&format!("{s}^0")),
};
result.with_context(|| anyhow::format_err!("failed to find {refkind} `{self}`"))
result.with_context(|| anyhow_original::format_err!("failed to find {refkind} `{self}`"))
}
/// Returns the kind of this [`ReferenceOrOid`].

View file

@ -16,14 +16,14 @@ use uv_version::version;
use crate::{Fetch, GitSource, Reporter};
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
pub enum GitResolverError {
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
Join(#[from] tokio::task::JoinError),
#[error("Git operation failed")]
Git(#[source] anyhow::Error),
Git(#[source] anyhow_original::Error),
#[error(transparent)]
Reqwest(#[from] reqwest::Error),
#[error(transparent)]
@ -158,7 +158,7 @@ impl GitResolver {
let fetch = tokio::task::spawn_blocking(move || source.fetch())
.await?
.map_err(GitResolverError::Git)?;
.map_err(|err: anyhow::Error| GitResolverError::Git(err.into()))?;
// Insert the resolved URL into the in-memory cache. This ensures that subsequent fetches
// resolve to the same precise commit.

View file

@ -16,6 +16,7 @@ owo-colors = { workspace = true }
regex = { workspace = true }
regex-automata = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tracing = { workspace = true }
walkdir = { workspace = true }

View file

@ -5,7 +5,7 @@ use globset::{Glob, GlobBuilder};
use owo_colors::OwoColorize;
use thiserror::Error;
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum PortableGlobError {
/// Shows the failing glob in the error message.
#[error(transparent)]

View file

@ -47,6 +47,7 @@ serde_json = { workspace = true }
sha2 = { workspace = true }
tempfile = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tracing = { workspace = true }
walkdir = { workspace = true }

View file

@ -36,7 +36,7 @@ pub struct Layout {
}
/// Note: The caller is responsible for adding the path of the wheel we're installing.
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum Error {
#[error(transparent)]
Io(#[from] io::Error),

View file

@ -44,6 +44,7 @@ rustc-hash = { workspace = true }
same-file = { workspace = true }
tempfile = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
url = { workspace = true }

View file

@ -22,7 +22,7 @@ const COMPILEALL_SCRIPT: &str = include_str!("pip_compileall.py");
/// This is longer than any compilation should ever take.
const COMPILE_TIMEOUT: Duration = Duration::from_secs(60);
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum CompileError {
#[error("Failed to list files in `site-packages`")]
Walkdir(#[from] walkdir::Error),

View file

@ -210,7 +210,7 @@ impl<'a, Context: BuildContext> Preparer<'a, Context> {
}
}
#[derive(thiserror::Error, Debug)]
#[derive(traversable_error::TraversableError, thiserror::Error, Debug)]
pub enum Error {
#[error("Building source distributions is disabled, but attempted to build `{0}`")]
NoBuild(PackageName),

View file

@ -24,7 +24,7 @@ pub async fn uninstall(
Ok(uninstall)
}
#[derive(thiserror::Error, Debug)]
#[derive(traversable_error::TraversableError, thiserror::Error, Debug)]
pub enum UninstallError {
#[error("Unable to uninstall `{0}`. distutils-installed distributions do not include the metadata required to uninstall safely.")]
Distutils(InstalledEggInfoFile),

View file

@ -21,6 +21,7 @@ async_zip = { workspace = true }
fs-err = { workspace = true }
futures = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tokio = { workspace = true }
tokio-util = { workspace = true }
tracing = { workspace = true }

View file

@ -15,7 +15,7 @@ use uv_pypi_types::ResolutionMetadata;
use zip::ZipArchive;
/// The caller is responsible for attaching the path or url we failed to read.
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum Error {
#[error("Failed to read `dist-info` metadata from built wheel")]
DistInfo,

View file

@ -33,6 +33,7 @@ schemars = { workspace = true, optional = true }
serde = { workspace = true, features = ["derive", "rc"] }
smallvec = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tracing = { workspace = true, optional = true }
unicode-width = { workspace = true }
url = { workspace = true, features = ["serde"] }

View file

@ -67,7 +67,7 @@ pub struct Pep508Error<T: Pep508Url = VerbatimUrl> {
}
/// Either we have an error string from our parser or an upstream error from `url`
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum Pep508ErrorSource<T: Pep508Url = VerbatimUrl> {
/// An error from our parser.
#[error("{0}")]

View file

@ -317,7 +317,7 @@ impl Pep508Url for VerbatimUrl {
}
/// An error that can occur when parsing a [`VerbatimUrl`].
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum VerbatimUrlError {
/// Failed to parse a URL.
#[error(transparent)]

View file

@ -23,6 +23,7 @@ rkyv = { workspace = true}
rustc-hash = { workspace = true }
serde = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
[dev-dependencies]
insta = { version = "1.40.0" }

View file

@ -280,7 +280,7 @@ impl FromStr for AbiTag {
}
}
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error, PartialEq, Eq)]
pub enum ParseAbiTagError {
#[error("Unknown ABI tag format: {0}")]
UnknownFormat(String),

View file

@ -206,7 +206,7 @@ impl FromStr for LanguageTag {
}
}
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error, PartialEq, Eq)]
pub enum ParseLanguageTagError {
#[error("Unknown language tag format: {0}")]
UnknownFormat(String),

View file

@ -5,7 +5,7 @@ use std::{fmt, io};
use thiserror::Error;
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum PlatformError {
#[error(transparent)]
IOError(#[from] io::Error),

View file

@ -620,7 +620,7 @@ impl FromStr for PlatformTag {
}
}
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error, PartialEq, Eq)]
pub enum ParsePlatformTagError {
#[error("Unknown platform tag format: {0}")]
UnknownFormat(String),

View file

@ -10,7 +10,7 @@ use uv_small_str::SmallString;
use crate::{AbiTag, Arch, LanguageTag, Os, Platform, PlatformError, PlatformTag};
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
pub enum TagsError {
#[error(transparent)]
PlatformError(#[from] PlatformError),

View file

@ -40,6 +40,7 @@ rustc-hash = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tokio = { workspace = true }
tokio-util = { workspace = true , features = ["io"] }
tracing = { workspace = true }

View file

@ -43,7 +43,7 @@ use uv_warnings::{warn_user, warn_user_once};
use crate::trusted_publishing::TrustedPublishingError;
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum PublishError {
#[error("The publish path is not a valid glob pattern: `{0}`")]
Pattern(String, #[source] PatternError),
@ -81,7 +81,7 @@ pub enum PublishError {
}
/// Failure to get the metadata for a specific file.
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum PublishPrepareError {
#[error(transparent)]
Io(#[from] io::Error),
@ -100,7 +100,7 @@ pub enum PublishPrepareError {
}
/// Failure in or after (HTTP) transport for a specific file.
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum PublishSendError {
#[error("Failed to send POST request")]
ReqwestMiddleware(#[source] reqwest_middleware::Error),

View file

@ -14,7 +14,7 @@ use tracing::{debug, trace};
use url::Url;
use uv_static::EnvVars;
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum TrustedPublishingError {
#[error("Environment variable {0} not set, is the `id-token: write` permission missing?")]
MissingEnvVar(&'static str),

View file

@ -36,6 +36,7 @@ schemars = { workspace = true, optional = true }
serde = { workspace = true }
serde-untagged = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
toml_edit = { workspace = true }
tracing = { workspace = true }
url = { workspace = true }

View file

@ -20,7 +20,7 @@ pub fn base_url_join_relative(base: &str, relative: &str) -> Result<Url, JoinRel
///
/// The error message includes the URL (`base` or `maybe_relative`) passed to
/// `base_url_join_relative` that provoked the error.
#[derive(Clone, Debug, thiserror::Error)]
#[derive(Clone, Debug, traversable_error::TraversableError, thiserror::Error)]
pub enum JoinRelativeError {
#[error("Failed to parse URL: `{original}`")]
ParseError {

View file

@ -540,7 +540,7 @@ impl hashbrown::Equivalent<ConflictPackage> for ConflictPackageRef<'_> {
}
/// An error that occurs when the given conflicting set is invalid somehow.
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
pub enum ConflictError {
/// An error for when there are zero conflicting items.
#[error("Each set of conflicts must have at least two entries, but found none")]

View file

@ -12,7 +12,7 @@ use thiserror::Error;
#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Identifier(Box<str>);
#[derive(Debug, Clone, Error, traversable_error::TraversableError)]
#[derive(Debug, Clone, traversable_error::TraversableError, Error)]
pub enum IdentifierParseError {
#[error("An identifier must not be empty")]
Empty,

View file

@ -28,7 +28,7 @@ pub use requires_txt::RequiresTxt;
/// <https://github.com/PyO3/python-pkginfo-rs/blob/d719988323a0cfea86d4737116d7917f30e819e2/src/error.rs>
///
/// The error type
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum MetadataError {
#[error(transparent)]
MailParse(#[from] MailParseError),

View file

@ -12,7 +12,7 @@ use uv_pep508::{
use crate::{ArchiveInfo, DirInfo, DirectUrl, VcsInfo, VcsKind};
#[derive(Debug, Error)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum ParsedUrlError {
#[error("Unsupported URL prefix `{prefix}` in URL: `{url}` ({message})")]
UnsupportedUrlPrefix {

View file

@ -570,7 +570,7 @@ impl IntoIterator for HashDigests {
}
}
#[derive(thiserror::Error, Debug)]
#[derive(traversable_error::TraversableError, thiserror::Error, Debug)]
pub enum HashError {
#[error("Unexpected hash (expected `<algorithm>:<hash>`): {0}")]
InvalidStructure(String),

View file

@ -56,6 +56,7 @@ sys-info = { workspace = true }
target-lexicon = { workspace = true }
tempfile = { workspace = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tokio = { workspace = true }
tokio-util = { workspace = true, features = ["compat"] }
tracing = { workspace = true }

View file

@ -175,7 +175,7 @@ type FindPythonResult = Result<PythonInstallation, PythonNotFound>;
/// The result of failed Python installation discovery.
///
/// See [`FindPythonResult`].
#[derive(Clone, Debug, Error, traversable_error::TraversableError)]
#[derive(Clone, Debug, traversable_error::TraversableError, Error)]
pub struct PythonNotFound {
pub request: PythonRequest,
pub python_preference: PythonPreference,
@ -209,7 +209,7 @@ pub enum PythonSource {
ParentInterpreter,
}
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum Error {
#[error(transparent)]
Io(#[from] io::Error),

View file

@ -38,7 +38,7 @@ use crate::platform::{self, Arch, Libc, Os};
use crate::PythonVariant;
use crate::{Interpreter, PythonRequest, PythonVersion, VersionRequest};
#[derive(Error, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum Error {
#[error(transparent)]
Io(#[from] io::Error),
@ -1042,7 +1042,7 @@ impl Error {
pub(crate) fn from_reqwest_middleware(url: Url, err: reqwest_middleware::Error) -> Self {
match err {
reqwest_middleware::Error::Middleware(error) => {
Self::NetworkMiddlewareError(url, error)
Self::NetworkMiddlewareError(url, error.into())
}
reqwest_middleware::Error::Reqwest(error) => {
Self::NetworkError(url, WrappedReqwestError::from(error))

View file

@ -33,13 +33,13 @@ struct PythonEnvironmentShared {
/// The result of failed environment discovery.
///
/// Generally this is cast from [`PythonNotFound`] by [`PythonEnvironment::find`].
#[derive(Clone, Debug, Error, traversable_error::TraversableError)]
#[derive(Clone, Debug, traversable_error::TraversableError, Error)]
pub struct EnvironmentNotFound {
request: PythonRequest,
preference: EnvironmentPreference,
}
#[derive(Clone, Debug, Error, traversable_error::TraversableError)]
#[derive(Clone, Debug, traversable_error::TraversableError, Error)]
pub struct InvalidEnvironment {
path: PathBuf,
pub kind: InvalidEnvironmentKind,

View file

@ -4,7 +4,7 @@ use std::{
};
use thiserror::Error;
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum Error {
#[error("Unknown Python implementation `{0}`")]
UnknownImplementation(String),

View file

@ -253,7 +253,7 @@ impl PythonInstallation {
}
}
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum PythonInstallationKeyError {
#[error("Failed to parse Python installation key `{0}`: {1}")]
ParseError(String, String),

View file

@ -598,7 +598,7 @@ impl ExternallyManaged {
}
}
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub struct UnexpectedResponseError {
#[source]
pub(super) err: serde_json::Error,
@ -636,7 +636,7 @@ impl Display for UnexpectedResponseError {
}
}
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub struct StatusCodeError {
pub(super) code: ExitStatus,
pub(super) stdout: String,
@ -673,7 +673,7 @@ impl Display for StatusCodeError {
}
}
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum Error {
#[error("Failed to query Python interpreter")]
Io(#[from] io::Error),
@ -701,7 +701,7 @@ pub enum Error {
Encode(#[from] rmp_serde::encode::Error),
}
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub struct BrokenSymlink {
pub path: PathBuf,
/// Whether the interpreter path looks like a virtual environment.
@ -735,7 +735,7 @@ enum InterpreterInfoResult {
Success(Box<InterpreterInfo>),
}
#[derive(Debug, Error, traversable_error::TraversableError, Deserialize, Serialize)]
#[derive(Debug, traversable_error::TraversableError, Error, Deserialize, Serialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum InterpreterInfoError {
#[error("Could not detect a glibc or a musl libc (while running on Linux)")]

View file

@ -63,7 +63,7 @@ pub(crate) fn current_dir() -> Result<std::path::PathBuf, std::io::Error> {
.unwrap_or(std::env::current_dir())
}
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum Error {
#[error(transparent)]
Io(#[from] std::io::Error),

View file

@ -14,7 +14,7 @@ use thiserror::Error;
use tracing::trace;
use uv_fs::Simplified;
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum LibcDetectionError {
#[error("Could not detect either glibc version nor musl libc version, at least one of which is required")]
NoLibcFound,

View file

@ -31,7 +31,7 @@ pub fn patch_dylib_install_name(dylib: PathBuf) -> Result<(), Error> {
Ok(())
}
#[derive(thiserror::Error, Debug)]
#[derive(traversable_error::TraversableError, thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Io(#[from] std::io::Error),

View file

@ -27,7 +27,7 @@ use crate::platform::{Arch, Libc, Os};
use crate::python_version::PythonVersion;
use crate::{macos_dylib, sysconfig, PythonRequest, PythonVariant};
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum Error {
#[error(transparent)]
Io(#[from] io::Error),

View file

@ -5,7 +5,7 @@ use std::ops::Deref;
use std::{fmt, str::FromStr};
use thiserror::Error;
#[derive(Error, traversable_error::TraversableError, Debug)]
#[derive(traversable_error::TraversableError, Error, Debug)]
pub enum Error {
#[error("Unknown operating system: {0}")]
UnknownOs(String),

View file

@ -381,7 +381,7 @@ fn patch_pkgconfig(contents: &str) -> Option<String> {
}
}
#[derive(thiserror::Error, Debug)]
#[derive(traversable_error::TraversableError, thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Io(#[from] std::io::Error),

View file

@ -249,7 +249,7 @@ const fn is_python_whitespace(c: char) -> bool {
)
}
#[derive(thiserror::Error, Debug)]
#[derive(traversable_error::TraversableError, thiserror::Error, Debug)]
pub enum Error {
#[error("Missing opening brace")]
MissingOpenBrace,

View file

@ -48,7 +48,7 @@ pub struct PyVenvConfiguration {
pub(crate) version: Option<PythonVersion>,
}
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum Error {
#[error(transparent)]
Io(#[from] io::Error),

View file

@ -125,7 +125,7 @@ fn read_registry_entry(company: &str, tag: &str, tag_key: &Key) -> Option<Window
})
}
#[derive(Debug, Error, traversable_error::TraversableError)]
#[derive(Debug, traversable_error::TraversableError, Error)]
pub enum ManagedPep514Error {
#[error("Windows has an unknown pointer width for arch: `{_0}`")]
InvalidPointerSize(Arch),

View file

@ -30,6 +30,7 @@ memchr = { workspace = true }
reqwest = { workspace = true, optional = true }
reqwest-middleware = { workspace = true, optional = true }
thiserror = { workspace = true }
traversable-error = { workspace = true }
tracing = { workspace = true }
unscanny = { workspace = true }
url = { workspace = true }

View file

@ -41,9 +41,9 @@ use std::path::{Path, PathBuf};
use std::str::FromStr;
use tracing::instrument;
use traversable_error::TraversableError;
use unscanny::{Pattern, Scanner};
use url::Url;
#[cfg(feature = "http")]
use uv_client::BaseClient;
use uv_client::BaseClientBuilder;
@ -206,10 +206,10 @@ impl RequirementsTxt {
.await
.map_err(RequirementsTxtParserError::Io)
}
.map_err(|err| RequirementsTxtFileError {
file: requirements_txt.to_path_buf(),
error: err,
})?;
.map_err(|err| RequirementsTxtFileError {
file: requirements_txt.to_path_buf(),
error: err,
})?;
let requirements_dir = requirements_txt.parent().unwrap_or(working_dir);
let data = Self::parse_inner(
@ -960,7 +960,7 @@ async fn read_url_to_string(
}
/// Error parsing requirements.txt, wrapper with filename
#[derive(Debug)]
#[derive(Debug, TraversableError)]
pub struct RequirementsTxtFileError {
file: PathBuf,
error: RequirementsTxtParserError,

View file

@ -6,7 +6,7 @@ use uv_pep508::{
};
use uv_pypi_types::{ParsedDirectoryUrl, ParsedUrl, VerbatimParsedUrl};
#[derive(Debug, thiserror::Error)]
#[derive(Debug, traversable_error::TraversableError, thiserror::Error)]
pub enum EditableError {
#[error("Editable `{0}` must refer to a local directory")]
MissingVersion(PackageName),

Some files were not shown because too many files have changed in this diff Show more