Skip to content

Network failures should decode WinINet HRESULTs and include actionable proxy context #6319

Description

@starSumi

Brief description of your issue

When winget fails to refresh a source or download through WinINet, the user-facing error can be too low-level to act on:

InternetOpenUrl() failed.
0x80072efd : unknown error

In the case below, the failure was caused by local proxy configuration, but the output did not mention the effective proxy, the source URL being refreshed, or any recovery path such as checking proxy settings or using --no-proxy when available.

Steps to reproduce

Environment:

winget: v1.28.240
PowerShell: 7.6.3
Installed package: Microsoft.PowerShell 7.6.3.0
Source: winget -> https://cdn.winget.microsoft.com/cache

Proxy state:

WinHTTP proxy: 127.0.0.1:7090
WinINet/user proxy: 127.0.0.1:7091
Git proxy: http://127.0.0.1:7091
127.0.0.1:7090: not listening
127.0.0.1:7091: listening, but TLS through it fails after CONNECT

Run:

winget upgrade --id Microsoft.PowerShell --source winget --accept-package-agreements --accept-source-agreements --disable-interactivity

Expected behavior

The error should expose enough context to diagnose the failure. For example:

  • Decode 0x80072efd as a WinINet/Win32 connection failure instead of unknown error.
  • Include the source name or URL involved, where safe.
  • Include whether a winget proxy/default proxy is active, where safe and without leaking credentials.
  • Suggest relevant recovery actions, such as checking proxy settings or trying --no-proxy if enabled.

Actual behavior

尝试更新源失败: winget
执行此命令时发生意外错误:
InternetOpenUrl() failed.
0x80072efd : unknown error

The same URL succeeds when bypassing the proxy:

curl.exe -I --noproxy "*" https://cdn.winget.microsoft.com/cache/source.msix
HTTP/1.1 200 OK
Content-Length: 17357706

The same URL through the local proxy fails:

curl.exe -I --proxy http://127.0.0.1:7091 https://cdn.winget.microsoft.com/cache/source.msix
HTTP/1.1 200 Connection established
curl: (35) schannel: failed to receive handshake, SSL/TLS connection failed

Source-level triage

Local checkout: microsoft/winget-cli at 5eb96e8.

Relevant paths:

  • src/AppInstallerCommonCore/Downloader.cpp
    • logs WinINet downloading from url
    • reads Network().GetProxyUri()
    • calls InternetOpenUrl(...)
    • throws THROW_LAST_ERROR_IF_NULL_MSG(urlFile, "InternetOpenUrl() failed.")
  • src/AppInstallerSharedLib/Errors.cpp
    • GetUserPresentableMessageForHR prints 0x... : ...
    • unknown external HRESULTs fall through to std::system_category().message(hr)
  • src/AppInstallerCLICore/Workflows/WorkflowBase.cpp
    • catches wil::ResultException
    • writes UnexpectedErrorExecutingCommand plus GetUserPresentableMessage(re)

0x80072efd is HRESULT_FROM_WIN32(ERROR_INTERNET_CANNOT_CONNECT). The current rendering appears to pass the full HRESULT to the system category instead of decoding the Win32 code via HRESULT_CODE(hr), which can produce unknown error.

Suggested fix direction

Minimal:

  • In Errors.cpp, when an HRESULT has FACILITY_WIN32, use HRESULT_CODE(hr) for the system message.

Better diagnostic:

  • In Downloader.cpp, enrich InternetOpenUrl() failure context with URL/source and proxy mode.
  • Redact credentials if a proxy URI is printed.

Tests:

  • Extend src/AppInstallerCLITests/Errors.cpp for HRESULT_FROM_WIN32(ERROR_INTERNET_CANNOT_CONNECT) and assert the user message is no longer unknown error.
  • Add a workflow-level test using a download hook that throws HRESULT_FROM_WIN32(ERROR_INTERNET_CANNOT_CONNECT) and asserts the output includes a useful diagnostic.

Related issues / PRs

This issue is intended as a narrow diagnostic enhancement, not another connectivity bug report.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs-TriageIssue needs to be triaged

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions