winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 1b87a14a657a5041b4291ff4f436707ab0be03ff
parent 88a69d85f73a2f28adaa4e5780cb159201ff8f10
Author: Ruben Guerrero <rubengu@microsoft.com>
Date:   Mon, 13 Sep 2021 10:29:43 -0700

Fix crash when resource.pri is not present (#1443)


Diffstat:
M.github/actions/spelling/expect.txt | 1+
Msrc/AppInstallerCLICore/Command.cpp | 6++++++
Msrc/AppInstallerCLICore/Resources.cpp | 26+++++++++++++++++++++++---
Msrc/AppInstallerCLICore/Resources.h | 10++++++++++
Msrc/AppInstallerCommonCore/Errors.cpp | 4+++-
Msrc/AppInstallerCommonCore/Public/AppInstallerErrors.h | 1+
6 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt @@ -247,6 +247,7 @@ pkindex PMS positionals powertoys +pri processthreads productcode pseudocode diff --git a/src/AppInstallerCLICore/Command.cpp b/src/AppInstallerCLICore/Command.cpp @@ -879,6 +879,12 @@ namespace AppInstaller::CLI context.Reporter.Error() << Resource::String::DisabledByGroupPolicy << ": "_liv << policy.PolicyName() << std::endl; return APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY; } + catch (const Resource::ResourceOpenException& e) + { + Logging::Telemetry().LogException(command->FullName(), "ResourceOpenException", e.what()); + context.Reporter.Error() << GetUserPresentableMessage(e) << std::endl; + return APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE; + } catch (const std::exception& e) { Logging::Telemetry().LogException(command->FullName(), "std::exception", e.what()); diff --git a/src/AppInstallerCLICore/Resources.cpp b/src/AppInstallerCLICore/Resources.cpp @@ -5,7 +5,6 @@ using namespace AppInstaller::Utility::literals; - namespace AppInstaller::CLI::Resource { LocString::LocString(StringId id) : Utility::LocIndString(Loader::Instance().ResolveString(id)) {} @@ -16,9 +15,25 @@ namespace AppInstaller::CLI::Resource return instance; } - Loader::Loader() + Loader::Loader() : m_wingetLoader(nullptr) { - m_wingetLoader = winrt::Windows::ApplicationModel::Resources::ResourceLoader::GetForViewIndependentUse(L"winget"); + try + { + // The default constructor of ResourceLoader throws a winrt::hresult_error exception + // when resource.pri is not found. ResourceLoader::GetForViewIndependentUse also throws + // a winrt::hresult_error but for reasons unknown it only gets catch when running on the + // debugger. Running without a debugger will result in a crash that not even adding a + // catch all fix. To provide a good error message we call the default constructor + // before calling GetForViewIndependentUse. + m_wingetLoader = winrt::Windows::ApplicationModel::Resources::ResourceLoader(); + m_wingetLoader = winrt::Windows::ApplicationModel::Resources::ResourceLoader::GetForViewIndependentUse(L"winget"); + } + catch (const winrt::hresult_error& hre) + { + // This message cannot be localized. + AICLI_LOG(CLI, Error, << "Failure loading resource file with error: " << hre.code()); + throw ResourceOpenException(hre); + } } std::string Loader::ResolveString( @@ -36,4 +51,9 @@ namespace AppInstaller::CLI::Resource THROW_HR(E_UNEXPECTED); } + + ResourceOpenException::ResourceOpenException(const winrt::hresult_error& hre) + { + m_message = "Could not open the resource file: " + GetUserPresentableMessage(hre); + } } diff --git a/src/AppInstallerCLICore/Resources.h b/src/AppInstallerCLICore/Resources.h @@ -345,6 +345,16 @@ namespace AppInstaller::CLI::Resource }; Utility::LocIndView GetFixedString(FixedString fs); + + struct ResourceOpenException : std::exception + { + ResourceOpenException(const winrt::hresult_error& hre); + + const char* what() const noexcept override { return m_message.c_str(); } + + private: + std::string m_message; + }; } inline std::ostream& operator<<(std::ostream& out, AppInstaller::CLI::Resource::StringId si) diff --git a/src/AppInstallerCommonCore/Errors.cpp b/src/AppInstallerCommonCore/Errors.cpp @@ -201,7 +201,9 @@ namespace AppInstaller #ifndef WINGET_DISABLE_FOR_FUZZING std::string GetUserPresentableMessage(const winrt::hresult_error& hre) { - return Utility::ConvertToUTF8(hre.message()); + std::ostringstream strstr; + GetUserPresentableMessageForHR(strstr, hre.code()); + return strstr.str(); } #endif } diff --git a/src/AppInstallerCommonCore/Public/AppInstallerErrors.h b/src/AppInstallerCommonCore/Public/AppInstallerErrors.h @@ -85,6 +85,7 @@ #define APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED ((HRESULT)0x8a150045) #define APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED ((HRESULT)0x8a150046) #define APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH ((HRESULT)0x8a150047) +#define APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE ((HRESULT)0x8a150048) namespace AppInstaller