Skip to content

Commit 585abc6

Browse files
committed
Defer reporting of build failures in resolver
1 parent d2b9036 commit 585abc6

File tree

4 files changed

+72
-53
lines changed

4 files changed

+72
-53
lines changed

crates/uv-resolver/src/error.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ pub enum ResolveError {
3232
#[error(transparent)]
3333
Client(#[from] uv_client::Error),
3434

35+
#[error(transparent)]
36+
Distribution(#[from] uv_distribution::Error),
37+
3538
#[error("The channel closed unexpectedly")]
3639
ChannelClosed,
3740

@@ -94,20 +97,20 @@ pub enum ResolveError {
9497
ParsedUrl(#[from] uv_pypi_types::ParsedUrlError),
9598

9699
#[error("Failed to download `{0}`")]
97-
Download(Box<BuiltDist>, #[source] uv_distribution::Error),
100+
Download(Box<BuiltDist>, #[source] Arc<uv_distribution::Error>),
98101

99102
#[error("Failed to download and build `{0}`")]
100-
DownloadAndBuild(Box<SourceDist>, #[source] uv_distribution::Error),
103+
DownloadAndBuild(Box<SourceDist>, #[source] Arc<uv_distribution::Error>),
101104

102105
#[error("Failed to read `{0}`")]
103-
Read(Box<BuiltDist>, #[source] uv_distribution::Error),
106+
Read(Box<BuiltDist>, #[source] Arc<uv_distribution::Error>),
104107

105108
// TODO(zanieb): Use `thiserror` in `InstalledDist` so we can avoid chaining `anyhow`
106109
#[error("Failed to read metadata from installed package `{0}`")]
107110
ReadInstalled(Box<InstalledDist>, #[source] anyhow::Error),
108111

109112
#[error("Failed to build `{0}`")]
110-
Build(Box<SourceDist>, #[source] uv_distribution::Error),
113+
Build(Box<SourceDist>, #[source] Arc<uv_distribution::Error>),
111114

112115
#[error(transparent)]
113116
NoSolution(#[from] NoSolutionError),

crates/uv-resolver/src/lock/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1241,7 +1241,7 @@ enum TagPolicy<'tags> {
12411241
/// Exclusively consider wheels that match the specified platform tags.
12421242
Required(&'tags Tags),
12431243
/// Prefer wheels that match the specified platform tags, but fall back to incompatible wheels
1244-
/// if necessary.
1244+
/// if necessary.
12451245
Preferred(&'tags Tags),
12461246
}
12471247

crates/uv-resolver/src/resolver/mod.rs

Lines changed: 57 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,32 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
945945
MetadataResponse::RequiresPython(..) => {
946946
unreachable!("`requires-python` is only known upfront for registry distributions")
947947
}
948+
MetadataResponse::Error(dist, err) => {
949+
return Err(match &**dist {
950+
Dist::Built(built_dist @ BuiltDist::Path(_)) => {
951+
ResolveError::Read(Box::new(built_dist.clone()), (*err).clone())
952+
}
953+
Dist::Source(source_dist @ SourceDist::Path(_)) => {
954+
ResolveError::Build(Box::new(source_dist.clone()), (*err).clone())
955+
}
956+
Dist::Source(source_dist @ SourceDist::Directory(_)) => {
957+
ResolveError::Build(Box::new(source_dist.clone()), (*err).clone())
958+
}
959+
Dist::Built(built_dist) => {
960+
ResolveError::Download(Box::new(built_dist.clone()), (*err).clone())
961+
}
962+
Dist::Source(source_dist) => {
963+
if source_dist.is_local() {
964+
ResolveError::Build(Box::new(source_dist.clone()), (*err).clone())
965+
} else {
966+
ResolveError::DownloadAndBuild(
967+
Box::new(source_dist.clone()),
968+
(*err).clone(),
969+
)
970+
}
971+
}
972+
});
973+
}
948974
};
949975

950976
let version = &metadata.version;
@@ -1331,6 +1357,35 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
13311357
UnavailableVersion::RequiresPython(requires_python.clone()),
13321358
));
13331359
}
1360+
MetadataResponse::Error(dist, err) => {
1361+
return Err(match &**dist {
1362+
Dist::Built(built_dist @ BuiltDist::Path(_)) => {
1363+
ResolveError::Read(Box::new(built_dist.clone()), (*err).clone())
1364+
}
1365+
Dist::Source(source_dist @ SourceDist::Path(_)) => {
1366+
ResolveError::Build(Box::new(source_dist.clone()), (*err).clone())
1367+
}
1368+
Dist::Source(source_dist @ SourceDist::Directory(_)) => {
1369+
ResolveError::Build(Box::new(source_dist.clone()), (*err).clone())
1370+
}
1371+
Dist::Built(built_dist) => {
1372+
ResolveError::Download(Box::new(built_dist.clone()), (*err).clone())
1373+
}
1374+
Dist::Source(source_dist) => {
1375+
if source_dist.is_local() {
1376+
ResolveError::Build(
1377+
Box::new(source_dist.clone()),
1378+
(*err).clone(),
1379+
)
1380+
} else {
1381+
ResolveError::DownloadAndBuild(
1382+
Box::new(source_dist.clone()),
1383+
(*err).clone(),
1384+
)
1385+
}
1386+
}
1387+
});
1388+
}
13341389
};
13351390

13361391
if let Some(err) =
@@ -1791,28 +1846,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
17911846
let metadata = provider
17921847
.get_or_build_wheel_metadata(&dist)
17931848
.boxed_local()
1794-
.await
1795-
.map_err(|err| match dist.clone() {
1796-
Dist::Built(built_dist @ BuiltDist::Path(_)) => {
1797-
ResolveError::Read(Box::new(built_dist), err)
1798-
}
1799-
Dist::Source(source_dist @ SourceDist::Path(_)) => {
1800-
ResolveError::Build(Box::new(source_dist), err)
1801-
}
1802-
Dist::Source(source_dist @ SourceDist::Directory(_)) => {
1803-
ResolveError::Build(Box::new(source_dist), err)
1804-
}
1805-
Dist::Built(built_dist) => {
1806-
ResolveError::Download(Box::new(built_dist), err)
1807-
}
1808-
Dist::Source(source_dist) => {
1809-
if source_dist.is_local() {
1810-
ResolveError::Build(Box::new(source_dist), err)
1811-
} else {
1812-
ResolveError::DownloadAndBuild(Box::new(source_dist), err)
1813-
}
1814-
}
1815-
})?;
1849+
.await?;
18161850

18171851
Ok(Some(Response::Dist { dist, metadata }))
18181852
}
@@ -1928,31 +1962,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
19281962
let metadata = provider
19291963
.get_or_build_wheel_metadata(&dist)
19301964
.boxed_local()
1931-
.await
1932-
.map_err(|err| match dist.clone() {
1933-
Dist::Built(built_dist @ BuiltDist::Path(_)) => {
1934-
ResolveError::Read(Box::new(built_dist), err)
1935-
}
1936-
Dist::Source(source_dist @ SourceDist::Path(_)) => {
1937-
ResolveError::Build(Box::new(source_dist), err)
1938-
}
1939-
Dist::Source(source_dist @ SourceDist::Directory(_)) => {
1940-
ResolveError::Build(Box::new(source_dist), err)
1941-
}
1942-
Dist::Built(built_dist) => {
1943-
ResolveError::Download(Box::new(built_dist), err)
1944-
}
1945-
Dist::Source(source_dist) => {
1946-
if source_dist.is_local() {
1947-
ResolveError::Build(Box::new(source_dist), err)
1948-
} else {
1949-
ResolveError::DownloadAndBuild(
1950-
Box::new(source_dist),
1951-
err,
1952-
)
1953-
}
1954-
}
1955-
})?;
1965+
.await?;
19561966

19571967
Response::Dist { dist, metadata }
19581968
}

crates/uv-resolver/src/resolver/provider.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::future::Future;
2+
use std::sync::Arc;
23

34
use uv_configuration::BuildOptions;
45
use uv_distribution::{ArchiveMetadata, DistributionDatabase};
@@ -46,6 +47,8 @@ pub enum MetadataResponse {
4647
/// The source distribution has a `requires-python` requirement that is not met by the installed
4748
/// Python version (and static metadata is not available).
4849
RequiresPython(VersionSpecifiers, Version),
50+
/// The distribution could not be built or downloaded.
51+
Error(Box<Dist>, Arc<uv_distribution::Error>),
4952
}
5053

5154
pub trait ResolverProvider {
@@ -210,7 +213,10 @@ impl<'a, Context: BuildContext> ResolverProvider for DefaultResolverProvider<'a,
210213
uv_distribution::Error::RequiresPython(requires_python, version) => {
211214
Ok(MetadataResponse::RequiresPython(requires_python, version))
212215
}
213-
err => Err(err),
216+
err => Ok(MetadataResponse::Error(
217+
Box::new(dist.clone()),
218+
Arc::new(err),
219+
)),
214220
},
215221
}
216222
}

0 commit comments

Comments
 (0)