mirror of https://github.com/astral-sh/uv
Review
This commit is contained in:
parent
43b7eb76b6
commit
e6949b81e2
|
|
@ -3,6 +3,8 @@ use std::ops::Deref;
|
||||||
|
|
||||||
use async_http_range_reader::AsyncHttpRangeReaderError;
|
use async_http_range_reader::AsyncHttpRangeReaderError;
|
||||||
use async_zip::error::ZipError;
|
use async_zip::error::ZipError;
|
||||||
|
use http::StatusCode;
|
||||||
|
use rustc_hash::FxHashSet;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use uv_distribution_filename::{WheelFilename, WheelFilenameError};
|
use uv_distribution_filename::{WheelFilename, WheelFilenameError};
|
||||||
|
|
@ -278,7 +280,7 @@ pub enum ErrorKind {
|
||||||
/// Make sure the package name is spelled correctly and that you've
|
/// Make sure the package name is spelled correctly and that you've
|
||||||
/// configured the right registry to fetch it from.
|
/// configured the right registry to fetch it from.
|
||||||
#[error("Package `{0}` was not found in the registry")]
|
#[error("Package `{0}` was not found in the registry")]
|
||||||
StatusCodeError(PackageName),
|
StatusCodeError(PackageName, FxHashSet<StatusCode>),
|
||||||
|
|
||||||
/// The package was not found in the local (file-based) index.
|
/// The package was not found in the local (file-based) index.
|
||||||
#[error("Package `{0}` was not found in the local index")]
|
#[error("Package `{0}` was not found in the local index")]
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ use std::fmt::Debug;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use async_http_range_reader::AsyncHttpRangeReader;
|
use async_http_range_reader::AsyncHttpRangeReader;
|
||||||
|
|
@ -11,7 +10,7 @@ use futures::{FutureExt, StreamExt, TryStreamExt};
|
||||||
use http::{HeaderMap, StatusCode};
|
use http::{HeaderMap, StatusCode};
|
||||||
use itertools::Either;
|
use itertools::Either;
|
||||||
use reqwest::{Proxy, Response};
|
use reqwest::{Proxy, Response};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use tokio::sync::{Mutex, Semaphore};
|
use tokio::sync::{Mutex, Semaphore};
|
||||||
use tracing::{Instrument, debug, info_span, instrument, trace, warn};
|
use tracing::{Instrument, debug, info_span, instrument, trace, warn};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
@ -325,7 +324,7 @@ impl RegistryClient {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut results = Vec::new();
|
let mut results = Vec::new();
|
||||||
let any_status_code_error = AtomicBool::new(false);
|
let status_code_errors = Arc::new(Mutex::new(FxHashSet::default()));
|
||||||
|
|
||||||
match self.index_strategy_for(package_name) {
|
match self.index_strategy_for(package_name) {
|
||||||
// If we're searching for the first index that contains the package, fetch serially.
|
// If we're searching for the first index that contains the package, fetch serially.
|
||||||
|
|
@ -357,7 +356,7 @@ impl RegistryClient {
|
||||||
debug!(
|
debug!(
|
||||||
"Indexes search failed because of status code failure: {status_code}"
|
"Indexes search failed because of status code failure: {status_code}"
|
||||||
);
|
);
|
||||||
any_status_code_error.store(true, Ordering::Relaxed);
|
status_code_errors.lock().await.insert(status_code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -394,8 +393,8 @@ impl RegistryClient {
|
||||||
{
|
{
|
||||||
SimpleMetadataSearchOutcome::Found(metadata) => Some(metadata),
|
SimpleMetadataSearchOutcome::Found(metadata) => Some(metadata),
|
||||||
SimpleMetadataSearchOutcome::NotFound => None,
|
SimpleMetadataSearchOutcome::NotFound => None,
|
||||||
SimpleMetadataSearchOutcome::StatusCodeFailure(_) => {
|
SimpleMetadataSearchOutcome::StatusCodeFailure(status_code) => {
|
||||||
any_status_code_error.store(true, Ordering::Relaxed);
|
status_code_errors.lock().await.insert(status_code);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -422,8 +421,13 @@ impl RegistryClient {
|
||||||
if results.is_empty() {
|
if results.is_empty() {
|
||||||
return match self.connectivity {
|
return match self.connectivity {
|
||||||
Connectivity::Online => {
|
Connectivity::Online => {
|
||||||
if any_status_code_error.load(Ordering::Relaxed) {
|
let status_code_errors = status_code_errors.lock().await;
|
||||||
Err(ErrorKind::StatusCodeError(package_name.clone()).into())
|
if !status_code_errors.is_empty() {
|
||||||
|
Err(ErrorKind::StatusCodeError(
|
||||||
|
package_name.clone(),
|
||||||
|
status_code_errors.clone(),
|
||||||
|
)
|
||||||
|
.into())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::PackageNotFound(package_name.clone()).into())
|
Err(ErrorKind::PackageNotFound(package_name.clone()).into())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -563,16 +563,18 @@ pub async fn check_url(
|
||||||
);
|
);
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
uv_client::ErrorKind::StatusCodeError(_) => {
|
uv_client::ErrorKind::StatusCodeError(_, status_code_error) => {
|
||||||
|
// TODO(konsti): We currently can't track that this must be exactly one status
|
||||||
|
// error with check URL.
|
||||||
|
debug_assert!(
|
||||||
|
status_code_error.len() == 1,
|
||||||
|
"Check URL must only check a single URL"
|
||||||
|
);
|
||||||
|
let status_code = status_code_error.iter().next();
|
||||||
// The package may or may not exist, there was an authentication failure.
|
// The package may or may not exist, there was an authentication failure.
|
||||||
// TODO(konsti): We should show the real index error instead.
|
let status_code_detail = status_code
|
||||||
let status_code_detail = if index_capabilities.unauthorized(index_url) {
|
.map(ToString::to_string)
|
||||||
"401 Unauthorized"
|
.unwrap_or("Status code error".to_string());
|
||||||
} else if index_capabilities.forbidden(index_url) {
|
|
||||||
"403 Forbidden"
|
|
||||||
} else {
|
|
||||||
"Status code error"
|
|
||||||
};
|
|
||||||
warn!(
|
warn!(
|
||||||
"Package not found in the registry; skipping upload check for {filename}"
|
"Package not found in the registry; skipping upload check for {filename}"
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ impl<Context: BuildContext> ResolverProvider for DefaultResolverProvider<'_, Con
|
||||||
)),
|
)),
|
||||||
Err(err) => match err.kind() {
|
Err(err) => match err.kind() {
|
||||||
uv_client::ErrorKind::PackageNotFound(_)
|
uv_client::ErrorKind::PackageNotFound(_)
|
||||||
| uv_client::ErrorKind::StatusCodeError(_) => {
|
| uv_client::ErrorKind::StatusCodeError(..) => {
|
||||||
if let Some(flat_index) = flat_index
|
if let Some(flat_index) = flat_index
|
||||||
.and_then(|flat_index| flat_index.get(package_name))
|
.and_then(|flat_index| flat_index.get(package_name))
|
||||||
.cloned()
|
.cloned()
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ impl LatestClient<'_> {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return match err.kind() {
|
return match err.kind() {
|
||||||
uv_client::ErrorKind::PackageNotFound(_)
|
uv_client::ErrorKind::PackageNotFound(_)
|
||||||
| uv_client::ErrorKind::StatusCodeError(_)
|
| uv_client::ErrorKind::StatusCodeError(..)
|
||||||
| uv_client::ErrorKind::NoIndex(_)
|
| uv_client::ErrorKind::NoIndex(_)
|
||||||
| uv_client::ErrorKind::Offline(_) => Ok(None),
|
| uv_client::ErrorKind::Offline(_) => Ok(None),
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue