From d454f9c34ba0f83b5047f3ba31aa02a1b7a2be0e Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Wed, 22 Jan 2025 11:54:02 -0500 Subject: [PATCH] Make GitHub fast path errors non-fatal (#10859) ## Summary For example: in the linked issue, the user has a symlink at `pyproject.toml`. The GitHub CDN doesn't give us any way to determine whether a file is a symlink, so we should just log the error and move on to the slow path. Closes https://github.com/astral-sh/uv/issues/10857 --- crates/uv-distribution/src/source/mod.rs | 58 +++++++++++++++--------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/crates/uv-distribution/src/source/mod.rs b/crates/uv-distribution/src/source/mod.rs index cf0996637cb6..80c868d40088 100644 --- a/crates/uv-distribution/src/source/mod.rs +++ b/crates/uv-distribution/src/source/mod.rs @@ -1499,39 +1499,55 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { } // If this is GitHub URL, attempt to resolve to a precise commit using the GitHub API. - if let Some(precise) = self + match self .build_context .git() .github_fast_path( resource.git, client.unmanaged.uncached_client(resource.url).clone(), ) - .await? + .await { - // There's no need to check the cache, since we can't use cached metadata if there are - // sources, and we can't know if there are sources without fetching the - // `pyproject.toml`. - // - // For the same reason, there's no need to write to the cache, since we won't be able to - // use it on subsequent runs. - if let Some(metadata) = self - .github_metadata(precise, source, resource, client) - .await? - { - // Validate the metadata, but ignore it if the metadata doesn't match. - match validate_metadata(source, &metadata) { - Ok(()) => { - debug!("Found static metadata via GitHub fast path for: {source}"); - return Ok(ArchiveMetadata { - metadata: Metadata::from_metadata23(metadata), - hashes: vec![], - }); + Ok(Some(precise)) => { + // There's no need to check the cache, since we can't use cached metadata if there are + // sources, and we can't know if there are sources without fetching the + // `pyproject.toml`. + // + // For the same reason, there's no need to write to the cache, since we won't be able to + // use it on subsequent runs. + match self + .github_metadata(precise, source, resource, client) + .await + { + Ok(Some(metadata)) => { + // Validate the metadata, but ignore it if the metadata doesn't match. + match validate_metadata(source, &metadata) { + Ok(()) => { + debug!("Found static metadata via GitHub fast path for: {source}"); + return Ok(ArchiveMetadata { + metadata: Metadata::from_metadata23(metadata), + hashes: vec![], + }); + } + Err(err) => { + debug!("Ignoring `pyproject.toml` from GitHub for {source}: {err}"); + } + } + } + Ok(None) => { + // Nothing to do. } Err(err) => { - debug!("Ignoring `pyproject.toml` from GitHub for {source}: {err}"); + debug!("Failed to fetch `pyproject.toml` via GitHub fast path for: {source} ({err})"); } } } + Ok(None) => { + // Nothing to do. + } + Err(err) => { + debug!("Failed to resolve commit via GitHub fast path for: {source} ({err})"); + } } // Fetch the Git repository.