Skip to content

Commit 7f38a8a

Browse files
committed
Handle not found errors better
1 parent 2a5b779 commit 7f38a8a

7 files changed

Lines changed: 70 additions & 9 deletions

File tree

crates/uv-auth/src/middleware.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::{
2222
index::{AuthPolicy, Indexes},
2323
realm::Realm,
2424
};
25-
use crate::{Index, TextCredentialStore, TomlCredentialError};
25+
use crate::{Index, TextCredentialStore};
2626

2727
/// Strategy for loading netrc files.
2828
enum NetrcMode {
@@ -81,7 +81,11 @@ impl Default for TextStoreMode {
8181
debug!("Loaded credential file {}", path.display());
8282
Some(store)
8383
}
84-
Err(TomlCredentialError::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => {
84+
Err(err)
85+
if err
86+
.as_io_error()
87+
.is_some_and(|err| err.kind() == std::io::ErrorKind::NotFound) =>
88+
{
8589
debug!("No credentials file found at {}", path.display());
8690
None
8791
}

crates/uv-auth/src/store.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@ impl AuthBackend {
3939
let path = TextCredentialStore::default_file()?;
4040
match TextCredentialStore::read(&path) {
4141
Ok((store, lock)) => Ok(Self::TextStore(store, lock)),
42-
Err(TomlCredentialError::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => {
42+
Err(err)
43+
if err
44+
.as_io_error()
45+
.is_some_and(|err| err.kind() == std::io::ErrorKind::NotFound) =>
46+
{
4347
Ok(Self::TextStore(
4448
TextCredentialStore::default(),
4549
TextCredentialStore::lock(&path)?,
@@ -86,6 +90,21 @@ pub enum TomlCredentialError {
8690
TokenNotUnicode(#[from] std::string::FromUtf8Error),
8791
}
8892

93+
impl TomlCredentialError {
94+
pub fn as_io_error(&self) -> Option<&std::io::Error> {
95+
match self {
96+
Self::Io(err) => Some(err),
97+
Self::LockedFile(err) => err.as_io_error(),
98+
Self::ParseError(_)
99+
| Self::SerializeError(_)
100+
| Self::BasicAuthError(_)
101+
| Self::BearerAuthError(_)
102+
| Self::CredentialsDirError
103+
| Self::TokenNotUnicode(_) => None,
104+
}
105+
}
106+
}
107+
89108
#[derive(Debug, Error)]
90109
pub enum BasicAuthError {
91110
#[error("`username` is required with `scheme = basic`")]

crates/uv-tool/src/lib.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,27 @@ pub enum Error {
9191
ToolEnvironmentNotFound(PackageName, PathBuf),
9292
}
9393

94+
impl Error {
95+
pub fn as_io_error(&self) -> Option<&io::Error> {
96+
match self {
97+
Self::Io(err) => Some(err),
98+
Self::LockedFile(err) => err.as_io_error(),
99+
Self::VirtualEnvError(uv_virtualenv::Error::Io(err)) => Some(err),
100+
Self::ReceiptWrite(_, _)
101+
| Self::ReceiptRead(_, _)
102+
| Self::VirtualEnvError(_)
103+
| Self::EntrypointRead(_)
104+
| Self::NoExecutableDirectory
105+
| Self::ToolName(_)
106+
| Self::EnvironmentError(_)
107+
| Self::MissingToolReceipt(_, _)
108+
| Self::EnvironmentRead(_, _)
109+
| Self::MissingToolPackage(_)
110+
| Self::ToolEnvironmentNotFound(_, _) => None,
111+
}
112+
}
113+
}
114+
94115
/// A collection of uv-managed tools installed on the current system.
95116
#[derive(Debug, Clone)]
96117
pub struct InstalledTools {

crates/uv/src/commands/tool/install.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,10 @@ pub(crate) async fn install(
335335
package_name.cyan()
336336
);
337337
}
338-
Err(uv_tool::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => {}
338+
Err(err)
339+
if err
340+
.as_io_error()
341+
.is_some_and(|err| err.kind() == std::io::ErrorKind::NotFound) => {}
339342
Err(err) => {
340343
return Err(err.into());
341344
}

crates/uv/src/commands/tool/list.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ pub(crate) async fn list(
2727
let installed_tools = InstalledTools::from_settings()?;
2828
let _lock = match installed_tools.lock().await {
2929
Ok(lock) => lock,
30-
Err(uv_tool::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => {
30+
Err(err)
31+
if err
32+
.as_io_error()
33+
.is_some_and(|err| err.kind() == std::io::ErrorKind::NotFound) =>
34+
{
3135
writeln!(printer.stderr(), "No tools installed")?;
3236
return Ok(ExitStatus::Success);
3337
}

crates/uv/src/commands/tool/run.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,11 @@ async fn show_help(
446446
let installed_tools = InstalledTools::from_settings()?;
447447
let _lock = match installed_tools.lock().await {
448448
Ok(lock) => lock,
449-
Err(uv_tool::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => {
449+
Err(err)
450+
if err
451+
.as_io_error()
452+
.is_some_and(|err| err.kind() == std::io::ErrorKind::NotFound) =>
453+
{
450454
writeln!(printer.stdout(), "{help}")?;
451455
return Ok(());
452456
}

crates/uv/src/commands/tool/uninstall.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ pub(crate) async fn uninstall(name: Vec<PackageName>, printer: Printer) -> Resul
1717
let installed_tools = InstalledTools::from_settings()?.init()?;
1818
let _lock = match installed_tools.lock().await {
1919
Ok(lock) => lock,
20-
Err(uv_tool::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => {
20+
Err(err)
21+
if err
22+
.as_io_error()
23+
.is_some_and(|err| err.kind() == std::io::ErrorKind::NotFound) =>
24+
{
2125
if !name.is_empty() {
2226
for name in name {
2327
writeln!(printer.stderr(), "`{name}` is not installed")?;
@@ -110,8 +114,10 @@ async fn do_uninstall(
110114
)?;
111115
continue;
112116
}
113-
Err(uv_tool::Error::VirtualEnvError(uv_virtualenv::Error::Io(err)))
114-
if err.kind() == std::io::ErrorKind::NotFound =>
117+
Err(err)
118+
if err
119+
.as_io_error()
120+
.is_some_and(|err| err.kind() == std::io::ErrorKind::NotFound) =>
115121
{
116122
bail!("`{name}` is not installed");
117123
}

0 commit comments

Comments
 (0)