diff --git a/vpd-manager/include/utility/json_utility.hpp b/vpd-manager/include/utility/json_utility.hpp
index 55010ad..9ecdf74 100644
--- a/vpd-manager/include/utility/json_utility.hpp
+++ b/vpd-manager/include/utility/json_utility.hpp
@@ -555,47 +555,56 @@
  * @param[in] i_sysCfgJsonObj - System config JSON object.
  * @param[in] i_vpdPath - Path to where VPD is stored.
  *
- * @throw std::runtime_error.
  * @return On success return valid path, on failure return empty string.
  */
 inline std::string getRedundantEepromPathFromJson(
-    const nlohmann::json& i_sysCfgJsonObj, const std::string& i_vpdPath)
+    const nlohmann::json& i_sysCfgJsonObj,
+    const std::string& i_vpdPath) noexcept
 {
-    if (i_vpdPath.empty())
+    try
     {
-        throw std::runtime_error("Path parameter is empty.");
-    }
-
-    if (!i_sysCfgJsonObj.contains("frus"))
-    {
-        throw std::runtime_error("Missing frus tag in system config JSON.");
-    }
-
-    // check if given path is FRU path
-    if (i_sysCfgJsonObj["frus"].contains(i_vpdPath))
-    {
-        return i_sysCfgJsonObj["frus"][i_vpdPath].at(0).value(
-            "redundantEeprom", "");
-    }
-
-    const nlohmann::json& l_fruList =
-        i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
-
-    for (const auto& l_fru : l_fruList.items())
-    {
-        const std::string& l_fruPath = l_fru.key();
-        const std::string& l_redundantFruPath =
-            i_sysCfgJsonObj["frus"][l_fruPath].at(0).value("redundantEeprom",
-                                                           "");
-
-        // check if given path is inventory path or redundant FRU path
-        if ((i_sysCfgJsonObj["frus"][l_fruPath].at(0).value("inventoryPath",
-                                                            "") == i_vpdPath) ||
-            (l_redundantFruPath == i_vpdPath))
+        if (i_vpdPath.empty())
         {
-            return l_redundantFruPath;
+            throw std::runtime_error("Path parameter is empty.");
+        }
+
+        if (!i_sysCfgJsonObj.contains("frus"))
+        {
+            throw std::runtime_error("Missing frus tag in system config JSON.");
+        }
+
+        // check if given path is FRU path
+        if (i_sysCfgJsonObj["frus"].contains(i_vpdPath))
+        {
+            return i_sysCfgJsonObj["frus"][i_vpdPath].at(0).value(
+                "redundantEeprom", "");
+        }
+
+        const nlohmann::json& l_fruList =
+            i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
+
+        for (const auto& l_fru : l_fruList.items())
+        {
+            const std::string& l_fruPath = l_fru.key();
+            const std::string& l_redundantFruPath =
+                i_sysCfgJsonObj["frus"][l_fruPath].at(0).value(
+                    "redundantEeprom", "");
+
+            // check if given path is inventory path or redundant FRU path
+            if ((i_sysCfgJsonObj["frus"][l_fruPath].at(0).value(
+                     "inventoryPath", "") == i_vpdPath) ||
+                (l_redundantFruPath == i_vpdPath))
+            {
+                return l_redundantFruPath;
+            }
         }
     }
+    catch (const std::exception& l_ex)
+    {
+        logging::logMessage("Failed to get redundant EEPROM path, error: " +
+                            std::string(l_ex.what()));
+    }
+
     return std::string();
 }
 
@@ -608,45 +617,52 @@
  * @param[in] i_sysCfgJsonObj - System config JSON object
  * @param[in] i_vpdPath - Path to where VPD is stored.
  *
- * @throw std::runtime_error.
- *
  * @return On success return valid path, on failure return empty string.
  */
 inline std::string getFruPathFromJson(const nlohmann::json& i_sysCfgJsonObj,
-                                      const std::string& i_vpdPath)
+                                      const std::string& i_vpdPath) noexcept
 {
-    if (i_vpdPath.empty())
+    try
     {
-        throw std::runtime_error("Path parameter is empty.");
-    }
-
-    if (!i_sysCfgJsonObj.contains("frus"))
-    {
-        throw std::runtime_error("Missing frus tag in system config JSON.");
-    }
-
-    // check if given path is FRU path
-    if (i_sysCfgJsonObj["frus"].contains(i_vpdPath))
-    {
-        return i_vpdPath;
-    }
-
-    const nlohmann::json& l_fruList =
-        i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
-
-    for (const auto& l_fru : l_fruList.items())
-    {
-        const auto l_fruPath = l_fru.key();
-
-        // check if given path is redundant FRU path or inventory path
-        if (i_vpdPath == i_sysCfgJsonObj["frus"][l_fruPath].at(0).value(
-                             "redundantEeprom", "") ||
-            (i_vpdPath == i_sysCfgJsonObj["frus"][l_fruPath].at(0).value(
-                              "inventoryPath", "")))
+        if (i_vpdPath.empty())
         {
-            return l_fruPath;
+            throw std::runtime_error("Path parameter is empty.");
+        }
+
+        if (!i_sysCfgJsonObj.contains("frus"))
+        {
+            throw std::runtime_error("Missing frus tag in system config JSON.");
+        }
+
+        // check if given path is FRU path
+        if (i_sysCfgJsonObj["frus"].contains(i_vpdPath))
+        {
+            return i_vpdPath;
+        }
+
+        const nlohmann::json& l_fruList =
+            i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
+
+        for (const auto& l_fru : l_fruList.items())
+        {
+            const auto l_fruPath = l_fru.key();
+
+            // check if given path is redundant FRU path or inventory path
+            if (i_vpdPath == i_sysCfgJsonObj["frus"][l_fruPath].at(0).value(
+                                 "redundantEeprom", "") ||
+                (i_vpdPath == i_sysCfgJsonObj["frus"][l_fruPath].at(0).value(
+                                  "inventoryPath", "")))
+            {
+                return l_fruPath;
+            }
         }
     }
+    catch (const std::exception& l_ex)
+    {
+        logging::logMessage("Failed to get FRU path from JSON, error: " +
+                            std::string(l_ex.what()));
+    }
+
     return std::string();
 }
 
@@ -740,33 +756,33 @@
  * a list of FRUs that needs polling. Returns an empty list if there are
  * no FRUs that requires polling.
  *
- * @throw std::runtime_error
- *
  * @param[in] i_sysCfgJsonObj - System config JSON object.
  *
- * @return list of FRUs parameters that needs polling.
+ * @return On success list of FRUs parameters that needs polling. On failure,
+ * empty list.
  */
 inline std::vector<std::string> getListOfGpioPollingFrus(
-    const nlohmann::json& i_sysCfgJsonObj)
+    const nlohmann::json& i_sysCfgJsonObj) noexcept
 {
-    if (i_sysCfgJsonObj.empty())
-    {
-        throw std::runtime_error("Invalid Parameters");
-    }
-
-    if (!i_sysCfgJsonObj.contains("frus"))
-    {
-        throw std::runtime_error("Missing frus section in system config JSON");
-    }
-
     std::vector<std::string> l_gpioPollingRequiredFrusList;
 
-    for (const auto& l_fru : i_sysCfgJsonObj["frus"].items())
+    try
     {
-        const auto l_fruPath = l_fru.key();
-
-        try
+        if (i_sysCfgJsonObj.empty())
         {
+            throw std::runtime_error("Invalid Parameters");
+        }
+
+        if (!i_sysCfgJsonObj.contains("frus"))
+        {
+            throw std::runtime_error(
+                "Missing frus section in system config JSON");
+        }
+
+        for (const auto& l_fru : i_sysCfgJsonObj["frus"].items())
+        {
+            const auto l_fruPath = l_fru.key();
+
             if (isActionRequired(i_sysCfgJsonObj, l_fruPath, "pollingRequired",
                                  "hotPlugging"))
             {
@@ -778,10 +794,11 @@
                 }
             }
         }
-        catch (const std::exception& l_ex)
-        {
-            logging::logMessage(l_ex.what());
-        }
+    }
+    catch (const std::exception& l_ex)
+    {
+        logging::logMessage("Failed to get list of GPIO polling FRUs, error: " +
+                            std::string(l_ex.what()));
     }
 
     return l_gpioPollingRequiredFrusList;
@@ -1015,42 +1032,50 @@
  *
  * The API will return a vector of FRUs inventory path which are replaceable at
  * standby.
- * The API can throw exception in case of error scenarios. Caller's
- * responsibility to handle those exceptions.
  *
  * @param[in] i_sysCfgJsonObj - System config JSON object.
  *
- * @return - List of FRUs replaceable at standby.
+ * @return - On success, list of FRUs replaceable at standby. On failure, empty
+ * vector.
  */
 inline std::vector<std::string> getListOfFrusReplaceableAtStandby(
-    const nlohmann::json& i_sysCfgJsonObj)
+    const nlohmann::json& i_sysCfgJsonObj) noexcept
 {
     std::vector<std::string> l_frusReplaceableAtStandby;
 
-    if (!i_sysCfgJsonObj.contains("frus"))
+    try
     {
-        logging::logMessage("Missing frus tag in system config JSON.");
-        return l_frusReplaceableAtStandby;
-    }
-
-    const nlohmann::json& l_fruList =
-        i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
-
-    for (const auto& l_fru : l_fruList.items())
-    {
-        if (i_sysCfgJsonObj["frus"][l_fru.key()].at(0).value(
-                "replaceableAtStandby", false))
+        if (!i_sysCfgJsonObj.contains("frus"))
         {
-            const std::string& l_inventoryObjectPath =
-                i_sysCfgJsonObj["frus"][l_fru.key()].at(0).value(
-                    "inventoryPath", "");
+            throw std::runtime_error("Missing frus tag in system config JSON.");
+        }
 
-            if (!l_inventoryObjectPath.empty())
+        const nlohmann::json& l_fruList =
+            i_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
+
+        for (const auto& l_fru : l_fruList.items())
+        {
+            if (i_sysCfgJsonObj["frus"][l_fru.key()].at(0).value(
+                    "replaceableAtStandby", false))
             {
-                l_frusReplaceableAtStandby.emplace_back(l_inventoryObjectPath);
+                const std::string& l_inventoryObjectPath =
+                    i_sysCfgJsonObj["frus"][l_fru.key()].at(0).value(
+                        "inventoryPath", "");
+
+                if (!l_inventoryObjectPath.empty())
+                {
+                    l_frusReplaceableAtStandby.emplace_back(
+                        l_inventoryObjectPath);
+                }
             }
         }
     }
+    catch (const std::exception& l_ex)
+    {
+        logging::logMessage(
+            "Failed to get list of FRUs replaceable at standby, error: " +
+            std::string(l_ex.what()));
+    }
 
     return l_frusReplaceableAtStandby;
 }
