winget-cli

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

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 }