Skip to content

Commit f7980a8

Browse files
committed
..
1 parent 540aac6 commit f7980a8

File tree

5 files changed

+36
-23
lines changed

5 files changed

+36
-23
lines changed

crates/uv-client/src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,9 @@ pub enum ErrorKind {
236236
#[error("Invalid `Content-Type` header for {0}")]
237237
InvalidContentTypeHeader(Url, #[source] http::header::ToStrError),
238238

239+
#[error("Invalid status code: {0}")]
240+
InvalidStatusCode(String),
241+
239242
#[error("Unsupported `Content-Type` \"{1}\" for {0}. Expected JSON or HTML.")]
240243
UnsupportedMediaType(Url, String),
241244

crates/uv-client/src/registry_client.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,10 @@ impl RegistryClient {
331331
let _permit = download_concurrency.acquire().await;
332332
match index.format {
333333
IndexFormat::Simple => {
334-
let status_code_strategy =
335-
self.index_urls.status_code_strategy_for(index.url);
334+
let status_code_strategy = self
335+
.index_urls
336+
.status_code_strategy_for(index.url)
337+
.map_err(|e| ErrorKind::InvalidStatusCode(e.to_string()))?;
336338
if let Some(metadata) = self
337339
.simple_single_index(
338340
package_name,
@@ -364,8 +366,10 @@ impl RegistryClient {
364366
let _permit = download_concurrency.acquire().await;
365367
match index.format {
366368
IndexFormat::Simple => {
367-
let status_code_strategy =
368-
self.index_urls.status_code_strategy_for(index.url);
369+
let status_code_strategy = self
370+
.index_urls
371+
.status_code_strategy_for(index.url)
372+
.map_err(|e| ErrorKind::InvalidStatusCode(e.to_string()))?;
369373
let metadata = self
370374
.simple_single_index(
371375
package_name,
@@ -506,11 +510,11 @@ impl RegistryClient {
506510
Err(err) => match err.into_kind() {
507511
// The package could not be found in the remote index.
508512
ErrorKind::WrappedReqwestError(url, err) => {
509-
let decision = if let Some(status) = err.status() {
510-
status_code_strategy.handle_status_code(status, index, capabilities)
511-
} else {
512-
IndexStatusCodeDecision::Stop
513-
};
513+
let decision = err
514+
.status()
515+
.map_or(IndexStatusCodeDecision::Stop, |status| {
516+
status_code_strategy.handle_status_code(status, index, capabilities)
517+
});
514518
match decision {
515519
IndexStatusCodeDecision::Continue => Ok(None),
516520
IndexStatusCodeDecision::Stop => {

crates/uv-distribution-types/src/index.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::path::Path;
22
use std::str::FromStr;
33

4+
use http::status::InvalidStatusCode;
45
use http::StatusCode;
56
use serde::{Deserialize, Deserializer, Serialize};
67
use thiserror::Error;
@@ -230,12 +231,12 @@ impl Index {
230231
}
231232

232233
/// Return the [`IndexStatusCodeStrategy`] for this index.
233-
pub fn status_code_strategy(&self) -> IndexStatusCodeStrategy {
234-
if !self.ignore_error_codes.is_empty() {
235-
IndexStatusCodeStrategy::from_ignored_error_codes(&self.ignore_error_codes)
234+
pub fn status_code_strategy(&self) -> Result<IndexStatusCodeStrategy, IndexSourceError> {
235+
Ok(if !self.ignore_error_codes.is_empty() {
236+
IndexStatusCodeStrategy::from_ignored_error_codes(&self.ignore_error_codes)?
236237
} else {
237238
IndexStatusCodeStrategy::from_index_url(self.url.url())
238-
}
239+
})
239240
}
240241
}
241242

@@ -403,4 +404,6 @@ pub enum IndexSourceError {
403404
IndexName(#[from] IndexNameError),
404405
#[error("Index included a name, but the name was empty")]
405406
EmptyName,
407+
#[error(transparent)]
408+
StatusCode(#[from] InvalidStatusCode),
406409
}

crates/uv-distribution-types/src/index_url.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use url::{ParseError, Url};
1313

1414
use uv_pep508::{split_scheme, Scheme, VerbatimUrl, VerbatimUrlError};
1515

16-
use crate::{Index, IndexStatusCodeStrategy, Verbatim};
16+
use crate::{Index, IndexSourceError, IndexStatusCodeStrategy, Verbatim};
1717

1818
static PYPI_URL: LazyLock<Url> = LazyLock::new(|| Url::parse("https://pypi.org/simple").unwrap());
1919

@@ -539,13 +539,16 @@ impl<'a> IndexUrls {
539539
}
540540

541541
/// Return the [`IndexStatusCodeStrategy`] for an [`IndexUrl`].
542-
pub fn status_code_strategy_for(&self, url: &IndexUrl) -> IndexStatusCodeStrategy {
542+
pub fn status_code_strategy_for(
543+
&self,
544+
url: &IndexUrl,
545+
) -> Result<IndexStatusCodeStrategy, IndexSourceError> {
543546
for index in &self.indexes {
544547
if index.url() == url {
545548
return index.status_code_strategy();
546549
}
547550
}
548-
IndexStatusCodeStrategy::Default
551+
Ok(IndexStatusCodeStrategy::Default)
549552
}
550553
}
551554

crates/uv-distribution-types/src/status_code_strategy.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use http::StatusCode;
1+
use http::{status::InvalidStatusCode, StatusCode};
22
use rustc_hash::FxHashSet;
33
use url::Url;
44

@@ -32,13 +32,12 @@ impl IndexStatusCodeStrategy {
3232
}
3333

3434
/// Derive a strategy from a list of status codes to ignore.
35-
pub fn from_ignored_error_codes(status_codes: &[u16]) -> Self {
35+
pub fn from_ignored_error_codes(status_codes: &[u16]) -> Result<Self, InvalidStatusCode> {
3636
let status_codes = status_codes
3737
.iter()
3838
.map(|code| StatusCode::from_u16(*code))
39-
.collect::<Result<FxHashSet<_>, _>>()
40-
.expect("Status codes should be valid.");
41-
Self::IgnoreErrorCodes { status_codes }
39+
.collect::<Result<FxHashSet<_>, _>>()?;
40+
Ok(Self::IgnoreErrorCodes { status_codes })
4241
}
4342

4443
/// Based on the strategy, decide whether to continue searching the next index
@@ -110,13 +109,14 @@ mod tests {
110109
}
111110

112111
#[test]
113-
fn test_strategy_custom_error_codes() {
112+
fn test_strategy_custom_error_codes() -> Result<()> {
114113
let status_codes =
115114
FxHashSet::from_iter(vec![StatusCode::UNAUTHORIZED, StatusCode::FORBIDDEN]);
116115
assert_eq!(
117-
IndexStatusCodeStrategy::from_ignored_error_codes(&[401, 403]),
116+
IndexStatusCodeStrategy::from_ignored_error_codes(&[401, 403])?,
118117
IndexStatusCodeStrategy::IgnoreErrorCodes { status_codes }
119118
);
119+
Ok(())
120120
}
121121

122122
#[test]

0 commit comments

Comments
 (0)