Skip to content

Do not replace registry errors with "<port> does not exist" - #2095

Open
Bugale Bugalit (bugale) wants to merge 1 commit into
microsoft:mainfrom
bugale:fix-registry-error-swallowing
Open

Do not replace registry errors with "<port> does not exist"#2095
Bugale Bugalit (bugale) wants to merge 1 commit into
microsoft:mainfrom
bugale:fix-registry-error-swallowing

Conversation

@bugale

Copy link
Copy Markdown
Contributor

Fixes #2094.

VersionedPortfileProviderImpl::entry() threw away the error returned by get_port_entry and substituted {package_name} does not exist, so any registry-level failure was reported as the port not existing.

get_port_entry returns ExpectedL<std::unique_ptr<RegistryEntry>> with three outcomes:

  1. error — something went wrong talking to the registry
  2. value, null pointer — the registry genuinely has no such port
  3. value, non-null — found

Case 2 is already handled downstream in load_control_file:

if (!ent->get())
{
    return msg::format_error(msgPortDoesNotExist, msg::package_name = version_spec.port_name);
}

so the else branch touched here is reached only for case 1. It also used msg::format rather than msg::format_error, so the line wasn't even prefixed with error:.

Before / after

This hid #2066 from us entirely. A concurrent git init race in the registries cache made get_port_entry fail, and the entire user-visible output was:

Fetching registry information from https://github.com/microsoft/vcpkg (HEAD)...
apr does not exist
apr-util does not exist
capstone does not exist
crc32c does not exist
expat does not exist
...

No error: prefix, no git output — just every port from the default registry declared non-existent, which points suspicion at the manifest or the baseline instead of at the registry fetch that actually failed. Finding the real message required a GIT_TRACE2_EVENT capture of a live failure:

could not lock config file .../registries/git/.git/config: File exists
could not set 'core.repositoryformatversion' to '0'

With this change that message reaches the user directly.

Worth noting: #2066 hit the same underlying failure but reached it through get_baseline_version, which propagates errors correctly — so that reporter saw the actual git error. The difference was entirely this one else branch.

The change

entry_it = m_entry_cache.emplace(name.to_string(), std::move(entry).error()).first;

ExpectedT::error() && already exists and the cache value type is constructible from LocalizedString, so this is a drop-in replacement for the discarded msg::format(...). msgPortDoesNotExist remains in use for the genuine cases at both other call sites in this file.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes misleading error reporting in the versioned registry port lookup path by preserving and surfacing the actual registry error returned from RegistryImplementation::get_port_entry(), instead of replacing it with a generic "<port> does not exist" message.

Changes:

  • In VersionedPortfileProviderImpl::entry(), propagate the ExpectedL error (std::move(entry).error()) into the cache rather than formatting msgPortDoesNotExist.
  • As a result, registry-level failures (git/network/filesystem/locking) now reach users directly via the existing ExpectedL error propagation path.

Comment thread src/vcpkg/portfileprovider.cpp Outdated
Comment on lines 439 to 446
msg::format(msgPortDoesNotExist, msg::package_name = name))
.first;
entry_it = m_entry_cache.emplace(name.to_string(), std::move(entry).error()).first;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this whole thing now just:

entry_it = m_entry_cache.emplace(name.to_string(), reg->get_port_entry(name)).first;

I believe what this was intending to do was preserve the error cases and map the "nullptr unique_ptr" case to the "port does not exist" error message. So I think it's good to not drop the "child" error but I think this is incorrectly dropping a legitimate error too.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed that you already discussed this in the description but the "is this whole thing now just" comment remains

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Billy O'Neal (@BillyONeal)
Yeah, you're right. Once the error is kept, both branches store the same thing, so the if/else does nothing. Pushed your version.
The nullptr case still gets the "does not exist" message, just one level up: entry() is only called from load_control_file, and that checks !ent->get() right after unwrapping. So a genuinely missing port reads the same as before, and a git or network failure now says what actually broke.

@BillyONeal
Billy O'Neal (BillyONeal) dismissed their stale review August 4, 2026 21:58

Oh I see my comment is addressed in the description

…rosoft#2094)

`VersionedPortfileProviderImpl::entry` discarded the error returned by
`get_port_entry` and substituted `msgPortDoesNotExist`, so registry
failures (network, git, filesystem) were reported as the port not existing.

The genuinely-missing-port case is a *value* holding a null pointer, and is
already handled by `load_control_file`; this `else` branch is only reached
when there is a real error. Cache the `ExpectedL` as-is so it survives.
Copilot AI review requested due to automatic review settings August 5, 2026 20:10
@bugale
Bugale Bugalit (bugale) force-pushed the fix-registry-error-swallowing branch from fb7e7dc to 2ca3cf7 Compare August 5, 2026 20:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Registry errors are reported as "<port> does not exist", hiding the real failure

3 participants