ErrorCommand.cpp (2955B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #include "pch.h" 4 #include "ErrorCommand.h" 5 #include "AppInstallerStrings.h" 6 #include "AppInstallerErrors.h" 7 #include "VTSupport.h" 8 9 namespace AppInstaller::CLI 10 { 11 namespace 12 { 13 // 0x12345678 : SYMBOL_VALUE 14 // Descriptive text 15 void OutputHResultInformation(Execution::Context& context, const Errors::HResultInformation& error) 16 { 17 auto info = context.Reporter.Info(); 18 info << VirtualTerminal::TextFormat::Foreground::Bright << "0x" << VirtualTerminal::TextFormat::Foreground::Bright << Logging::SetHRFormat << error.Value(); 19 if (!error.Symbol().empty()) 20 { 21 info << " : "_liv << VirtualTerminal::TextFormat::Foreground::BrightCyan << error.Symbol(); 22 } 23 info << std::endl; 24 info << error.GetDescription() << std::endl; 25 } 26 } 27 28 std::vector<Argument> ErrorCommand::GetArguments() const 29 { 30 return { 31 Argument{ Execution::Args::Type::ErrorInput, Resource::String::ErrorInputArgumentDescription, ArgumentType::Positional, true }, 32 }; 33 } 34 35 Resource::LocString ErrorCommand::ShortDescription() const 36 { 37 return { Resource::String::ErrorCommandShortDescription }; 38 } 39 40 Resource::LocString ErrorCommand::LongDescription() const 41 { 42 return { Resource::String::ErrorCommandLongDescription }; 43 } 44 45 void ErrorCommand::ExecuteInternal(Execution::Context& context) const 46 { 47 std::string input{ context.Args.GetArg(Execution::Args::Type::ErrorInput) }; 48 49 const char* begin = input.c_str(); 50 char* end = nullptr; 51 errno = 0; 52 HRESULT errorNumber = strtol(begin, &end, 0); 53 54 if (errno == ERANGE) 55 { 56 errno = 0; 57 unsigned long unsignedError = strtoul(begin, &end, 0); 58 59 if (errno == ERANGE) 60 { 61 context.Reporter.Error() << Resource::String::ErrorNumberIsTooLarge << std::endl; 62 AICLI_TERMINATE_CONTEXT(E_INVALIDARG); 63 } 64 65 errorNumber = static_cast<HRESULT>(unsignedError); 66 } 67 68 // If the entire string was consumed as a number, treat it as an HRESULT 69 if (static_cast<size_t>(end - begin) == input.length()) 70 { 71 auto error = Errors::HResultInformation::Find(errorNumber); 72 if (error) 73 { 74 OutputHResultInformation(context, *error); 75 } 76 } 77 // otherwise, treat it as a string and search our error list 78 else 79 { 80 auto errors = Errors::HResultInformation::Find(Utility::Trim(input)); 81 for (const auto& error : errors) 82 { 83 OutputHResultInformation(context, *error); 84 } 85 } 86 } 87 }