Skip to content

Format WinINet HRESULT messages#6321

Open
starSumi wants to merge 2 commits into
microsoft:masterfrom
starSumi:fix/6319-wininet-hresult-message
Open

Format WinINet HRESULT messages#6321
starSumi wants to merge 2 commits into
microsoft:masterfrom
starSumi:fix/6319-wininet-hresult-message

Conversation

@starSumi

@starSumi starSumi commented Jun 23, 2026

Copy link
Copy Markdown

Summary

Fixes #6319.

HRESULT_FROM_WIN32(ERROR_INTERNET_CANNOT_CONNECT) is a WinINet error. On MSVC, std::system_category().message(12029) and std::system_category().message(0x80072efd) both return unknown error, so decoding the HRESULT alone cannot provide the useful WinINet diagnostic.

This change decodes FACILITY_WIN32 HRESULTs and retrieves WinINet-range messages from wininet.dll, falling back to std::system_category for all other errors.

Changes

  • Centralize system error formatting for both user-facing HRESULT paths.
  • Retrieve localized WinINet messages from the WinINet message table.
  • Cover both GetUserPresentableMessage and HResultInformation::Find(...)->GetDescription().

Validation

  • Evidence: an isolated MSVC probe showed that the system category returns unknown error for both 12029 and 0x80072efd, while the WinINet message table returns the localized connection-failure message.
  • git diff --check passed.
  • An isolated MSVC probe verified that the system category returns unknown error for both values while the WinINet message table returns the localized connection-failure message.
  • I restored the NuGet packages locally, but could not run AppInstallerCLITests because the first-time vcpkg registry fetch was interrupted before the required historical port trees were available. The updated PR CI is queued for the x64 and x86 test validation.

Decode HRESULT_FROM_WIN32 values before asking std::system_category for user-facing text so WinINet errors do not render as unknown error.

Adds a regression test for ERROR_INTERNET_CANNOT_CONNECT.
@starSumi

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

@starSumi
starSumi marked this pull request as ready for review June 23, 2026 09:46
@starSumi
starSumi requested a review from a team as a code owner June 23, 2026 09:46
florelis
florelis previously approved these changes Jul 20, 2026
@florelis
florelis requested a review from Copilot July 20, 2026 22:24
@florelis

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

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 updates WinGet’s shared error formatting so that HRESULTs created via HRESULT_FROM_WIN32(...) are decoded back to their underlying Win32 error codes before retrieving a system error message, preventing “unknown error” output for Win32-facility HRESULTs. It also adds a regression test to validate the new behavior for a WinINet/Win32 error wrapped as an HRESULT.

Changes:

  • Decode FACILITY_WIN32 HRESULTs using HRESULT_CODE(hr) before calling std::system_category().message(...) in GetUserPresentableMessageForHR.
  • Add a Catch2 regression test for HRESULT_FROM_WIN32(ERROR_INTERNET_CANNOT_CONNECT) message formatting.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/AppInstallerSharedLib/Errors.cpp Adjusts user-presentable HRESULT formatting to use Win32 codes when facility is Win32.
src/AppInstallerCLITests/Errors.cpp Adds a regression test ensuring decoded Win32 messages appear for HRESULT_FROM_WIN32(...).

Comment thread src/AppInstallerSharedLib/Errors.cpp Outdated
Comment on lines 364 to 366
strstr << std::system_category().message(
HRESULT_FACILITY(hr) == FACILITY_WIN32 ? HRESULT_CODE(hr) : hr);
}
Comment thread src/AppInstallerCLITests/Errors.cpp Outdated
Comment on lines +22 to +35
TEST_CASE("Win32HResultMessageUsesWin32Code", "[errors]")
{
constexpr HRESULT internetCannotConnect = HRESULT_FROM_WIN32(ERROR_INTERNET_CANNOT_CONNECT);
const std::string message = GetUserPresentableMessage(internetCannotConnect);
const std::string expectedSystemMessage = std::system_category().message(ERROR_INTERNET_CANNOT_CONNECT);
const std::string hresultSystemMessage = std::system_category().message(internetCannotConnect);

INFO(message);
INFO(expectedSystemMessage);
INFO(hresultSystemMessage);
REQUIRE(message.find("0x80072efd") != std::string::npos);
REQUIRE(message.find(expectedSystemMessage) != std::string::npos);
REQUIRE(message.find(hresultSystemMessage) == std::string::npos);
} No newline at end of file
@starSumi starSumi changed the title Decode Win32 HRESULT messages before formatting Format WinINet HRESULT messages Jul 22, 2026
@starSumi

Copy link
Copy Markdown
Author

Follow-up: I found the cause of the previous x64 and x86 test failures. On MSVC, std::system_category().message(12029) and std::system_category().message(0x80072efd) both return unknown error, so decoding the HRESULT alone does not produce a WinINet message.

This update retrieves the localized message from wininet.dll for WinINet-range codes, uses the same helper in HResultInformation::GetDescription(), and extends the regression test to cover both user-facing paths.

Local validation: git diff --check passed, and an isolated MSVC probe verified the message-table behavior. I could not run AppInstallerCLITests locally because the first-time vcpkg registry fetch was interrupted before its historical port trees were available; the refreshed PR CI is queued for the x64 and x86 tests.

@starSumi

Copy link
Copy Markdown
Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Commenter does not have sufficient privileges for PR 6321 in repo microsoft/winget-cli

@starSumi

Copy link
Copy Markdown
Author

Azure reports that I do not have permission to queue the x64/x86 pipeline for the updated head eefe8e7. @florelis, could you please rerun it when convenient?

Evidence: the prior test failure was caused by the system-category assumption. This head now reads the WinINet message table and covers both user-facing formatting paths.

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.

Network failures should decode WinINet HRESULTs and include actionable proxy context

3 participants