From 396dc06799bd5ddb23c38cf33d21b0b08224ec9b Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 27 Aug 2025 14:36:26 -0500 Subject: [PATCH] Treat an invalid error on credential removal as a missing entry on Windows --- Cargo.lock | 1 + crates/uv-keyring/Cargo.toml | 1 + crates/uv-keyring/src/windows.rs | 16 +++++++++++----- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2b3f407fa..7bc5d4063 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5838,6 +5838,7 @@ dependencies = [ "secret-service", "security-framework", "tokio", + "tracing", "windows-sys 0.59.0", "zeroize", ] diff --git a/crates/uv-keyring/Cargo.toml b/crates/uv-keyring/Cargo.toml index 909b06d59..c124932c0 100644 --- a/crates/uv-keyring/Cargo.toml +++ b/crates/uv-keyring/Cargo.toml @@ -23,6 +23,7 @@ windows-native = ["dep:windows-sys", "dep:byteorder"] [dependencies] async-trait = { workspace = true } tokio = { workspace = true } +tracing = { workspace = true } [target.'cfg(target_os = "macos")'.dependencies] security-framework = { version = "3", optional = true } diff --git a/crates/uv-keyring/src/windows.rs b/crates/uv-keyring/src/windows.rs index d86444355..b8b979eda 100644 --- a/crates/uv-keyring/src/windows.rs +++ b/crates/uv-keyring/src/windows.rs @@ -44,9 +44,10 @@ use byteorder::{ByteOrder, LittleEndian}; use std::collections::HashMap; use std::iter::once; use std::str; +use tracing::debug; use windows_sys::Win32::Foundation::{ - ERROR_BAD_USERNAME, ERROR_ENVVAR_NOT_FOUND, ERROR_INVALID_FLAGS, ERROR_INVALID_PARAMETER, - ERROR_NO_SUCH_LOGON_SESSION, ERROR_NOT_FOUND, FILETIME, GetLastError, + ERROR_BAD_USERNAME, ERROR_ENVVAR_NOT_FOUND, ERROR_INVALID_FLAGS, ERROR_INVALID_HANDLE, + ERROR_INVALID_PARAMETER, ERROR_NO_SUCH_LOGON_SESSION, ERROR_NOT_FOUND, FILETIME, GetLastError, }; use windows_sys::Win32::Security::Credentials::{ CRED_FLAGS, CRED_MAX_CREDENTIAL_BLOB_SIZE, CRED_MAX_GENERIC_TARGET_NAME_LENGTH, @@ -500,9 +501,14 @@ pub fn decode_error() -> ErrorCode { // SAFETY: Calling Windows API match unsafe { GetLastError() } { ERROR_NOT_FOUND => ErrorCode::NoEntry, - // N.B. It's not clear why `ERROR_ENVVAR_NOT_FOUND` would be returned rather than - // `ERROR_NOT_FOUND`, but this was encountered on a Windows CI machine. - ERROR_ENVVAR_NOT_FOUND => ErrorCode::NoEntry, + // N.B. It's not clear why `ERROR_ENVVAR_NOT_FOUND` or `ERROR_INVALID_HANDLE` would be + // returned rather than `ERROR_NOT_FOUND`, but these were encountered on Windows CI machines. + err @ (ERROR_ENVVAR_NOT_FOUND | ERROR_INVALID_HANDLE) => { + debug!( + "Windows credential operation failed with error code {err}, treating it as a missing credential" + ); + ErrorCode::NoEntry + } ERROR_NO_SUCH_LOGON_SESSION => { ErrorCode::NoStorageAccess(wrap(ERROR_NO_SUCH_LOGON_SESSION)) }