Error handling for executeCmd API

This commit updates executeCmd API to set error code in case of error.
This helps the caller of API to take action based on the error code
returned from the API.

Change-Id: Ie5b7804f5d486a278765d460eabaef0bd46d555e
Signed-off-by: Rekha Aparna <vrekhaaparna@ibm.com>
diff --git a/vpd-manager/include/utility/common_utility.hpp b/vpd-manager/include/utility/common_utility.hpp
index dc5da28..6c28f5b 100644
--- a/vpd-manager/include/utility/common_utility.hpp
+++ b/vpd-manager/include/utility/common_utility.hpp
@@ -99,28 +99,45 @@
  * @throw std::runtime_error.
  *
  * @param[in] arguments for command
+ * @param[out] o_errCode - To set error code in case of error.
  * @returns output of that command
  */
 template <typename T, typename... Types>
-inline std::vector<std::string> executeCmd(T&& i_path, Types... i_args)
+inline std::vector<std::string> executeCmd(T&& i_path, uint16_t& o_errCode,
+                                           Types... i_args)
 {
+    o_errCode = 0;
     std::vector<std::string> l_cmdOutput;
-    std::array<char, constants::CMD_BUFFER_LENGTH> l_buffer;
 
-    std::string l_cmd = i_path + getCommand(i_args...);
-
-    std::unique_ptr<FILE, decltype(&pclose)> l_cmdPipe(
-        popen(l_cmd.c_str(), "r"), pclose);
-
-    if (!l_cmdPipe)
+    try
     {
-        logging::logMessage(
-            "popen failed with error " + std::string(strerror(errno)));
-        throw std::runtime_error("popen failed!");
+        std::array<char, constants::CMD_BUFFER_LENGTH> l_buffer;
+
+        std::string l_cmd = i_path + getCommand(i_args...);
+
+        std::unique_ptr<FILE, decltype(&pclose)> l_cmdPipe(
+            popen(l_cmd.c_str(), "r"), pclose);
+
+        if (!l_cmdPipe)
+        {
+            o_errCode = error_code::POPEN_FAILED;
+            Logger::getLoggerInstance()->logMessage(
+                "popen failed with error " + std::string(strerror(errno)));
+            return l_cmdOutput;
+        }
+
+        while (fgets(l_buffer.data(), l_buffer.size(), l_cmdPipe.get()) !=
+               nullptr)
+        {
+            l_cmdOutput.emplace_back(l_buffer.data());
+        }
     }
-    while (fgets(l_buffer.data(), l_buffer.size(), l_cmdPipe.get()) != nullptr)
+    catch (const std::exception& l_ex)
     {
-        l_cmdOutput.emplace_back(l_buffer.data());
+        o_errCode = error_code::STANDARD_EXCEPTION;
+        Logger::getLoggerInstance()->logMessage(
+            "Error while trying to execute command [" + std::string(i_path) +
+            "], error : " + std::string(l_ex.what()));
     }
 
     return l_cmdOutput;
@@ -283,8 +300,9 @@
 {
     try
     {
+        uint16_t l_errCode = 0;
         std::vector<std::string> l_cmdOutput =
-            executeCmd("/sbin/fw_printenv fieldmode");
+            executeCmd("/sbin/fw_printenv fieldmode", l_errCode);
 
         if (l_cmdOutput.size() > 0)
         {
@@ -292,9 +310,15 @@
 
             // Remove the new line character from the string.
             l_cmdOutput[0].erase(l_cmdOutput[0].length() - 1);
-
             return l_cmdOutput[0] == "fieldmode=true";
         }
+        else if (l_errCode)
+        {
+            // ToDo : Remove log and set error code.
+            Logger::getLoggerInstance()->logMessage(
+                "Failed to execute command, error : " +
+                getErrCodeMsg(l_errCode));
+        }
     }
     catch (const std::exception& l_ex)
     {}
@@ -315,11 +339,12 @@
 inline types::VpdCollectionMode getVpdCollectionMode(
     uint16_t& o_errCode) noexcept
 {
+    o_errCode = 0;
     types::VpdCollectionMode l_result{types::VpdCollectionMode::DEFAULT_MODE};
     try
     {
         std::vector<std::string> l_cmdOutput =
-            commonUtility::executeCmd("/sbin/fw_printenv vpdmode");
+            commonUtility::executeCmd("/sbin/fw_printenv vpdmode", o_errCode);
 
         if (l_cmdOutput.size() > 0)
         {