API to get error info based on the exception

This commit implements an event logger API to extract the error info
based on the exception type.

Change-Id: I132306a6d3127253435e53f61328843fa8f1be24
Signed-off-by: Anupama B R <anupama.b.r1@ibm.com>
diff --git a/vpd-manager/include/event_logger.hpp b/vpd-manager/include/event_logger.hpp
index 0080be6..7c466ce 100644
--- a/vpd-manager/include/event_logger.hpp
+++ b/vpd-manager/include/event_logger.hpp
@@ -160,6 +160,17 @@
         const std::optional<std::string> i_procedure);
 
   private:
+    /**
+     * @brief API to get error info based on the exception.
+     *
+     * @param[in] i_exception - Exception object.
+     *
+     * @return - Valid ExceptionDataMap on success, otherwise map having default
+     * value.
+     */
+    static types::ExceptionDataMap getExceptionData(
+        const std::exception& i_exception);
+
     static const std::unordered_map<types::SeverityType, std::string>
         m_severityMap;
     static const std::unordered_map<types::ErrorType, std::string>
diff --git a/vpd-manager/include/types.hpp b/vpd-manager/include/types.hpp
index 37affa7..7dacb26 100644
--- a/vpd-manager/include/types.hpp
+++ b/vpd-manager/include/types.hpp
@@ -190,5 +190,9 @@
 using InventoryCalloutData = std::tuple<std::string, CalloutPriority>;
 using DeviceCalloutData = std::tuple<std::string, std::string>;
 using I2cBusCalloutData = std::tuple<std::string, std::string, std::string>;
+
+using ExceptionInfoVariant = std::variant<std::monostate, ErrorType, std::string>;
+/* Error info map of format <Error format, Value> */
+using ExceptionDataMap = std::map<std::string, ExceptionInfoVariant>;
 } // namespace types
 } // namespace vpd
diff --git a/vpd-manager/src/event_logger.cpp b/vpd-manager/src/event_logger.cpp
index eb2f470..893f4e1 100644
--- a/vpd-manager/src/event_logger.cpp
+++ b/vpd-manager/src/event_logger.cpp
@@ -1,5 +1,6 @@
 #include "event_logger.hpp"
 
+#include "exceptions.hpp"
 #include "logger.hpp"
 
 #include <systemd/sd-bus.h>
@@ -294,4 +295,79 @@
                             std::string(l_ex.what()));
     }
 }
+
+types::ExceptionDataMap EventLogger::getExceptionData(
+    const std::exception& i_exception)
+{
+    types::ExceptionDataMap l_errorInfo{
+        {"ErrorType", types::ErrorType::InternalFailure},
+        {"ErrorMsg", i_exception.what()}};
+
+    try
+    {
+        if (typeid(i_exception) == typeid(DataException))
+        {
+            const DataException& l_ex =
+                dynamic_cast<const DataException&>(i_exception);
+            l_errorInfo["ErrorType"] = l_ex.getErrorType();
+            l_errorInfo["ErrorMsg"] =
+                std::string("Data Exception. Reason: ") + i_exception.what();
+        }
+        else if (typeid(i_exception) == typeid(EccException))
+        {
+            const EccException& l_ex =
+                dynamic_cast<const EccException&>(i_exception);
+            l_errorInfo["ErrorType"] = l_ex.getErrorType();
+            l_errorInfo["ErrorMsg"] =
+                std::string("Ecc Exception. Reason: ") + i_exception.what();
+        }
+        else if (typeid(i_exception) == typeid(JsonException))
+        {
+            const JsonException& l_ex =
+                dynamic_cast<const JsonException&>(i_exception);
+            l_errorInfo["ErrorType"] = l_ex.getErrorType();
+            l_errorInfo["ErrorMsg"] =
+                std::string("Json Exception. Reason: ") + i_exception.what();
+        }
+        else if (typeid(i_exception) == typeid(GpioException))
+        {
+            const GpioException& l_ex =
+                dynamic_cast<const GpioException&>(i_exception);
+            l_errorInfo["ErrorType"] = l_ex.getErrorType();
+            l_errorInfo["ErrorMsg"] =
+                std::string("Gpio Exception. Reason: ") + i_exception.what();
+        }
+        else if (typeid(i_exception) == typeid(DbusException))
+        {
+            const DbusException& l_ex =
+                dynamic_cast<const DbusException&>(i_exception);
+            l_errorInfo["ErrorType"] = l_ex.getErrorType();
+            l_errorInfo["ErrorMsg"] =
+                std::string("Dbus Exception. Reason: ") + i_exception.what();
+        }
+        else if (typeid(i_exception) == typeid(FirmwareException))
+        {
+            const FirmwareException& l_ex =
+                dynamic_cast<const FirmwareException&>(i_exception);
+            l_errorInfo["ErrorType"] = l_ex.getErrorType();
+            l_errorInfo["ErrorMsg"] =
+                std::string("Firmware Exception. Reason: ") +
+                i_exception.what();
+        }
+        else if (typeid(i_exception) == typeid(EepromException))
+        {
+            const EepromException& l_ex =
+                dynamic_cast<const EepromException&>(i_exception);
+            l_errorInfo["ErrorType"] = l_ex.getErrorType();
+            l_errorInfo["ErrorMsg"] =
+                std::string("Eeprom Exception. Reason: ") + i_exception.what();
+        }
+    }
+    catch (const std::exception& l_ex)
+    {
+        logging::logMessage(
+            "Failed to get error info, reason: " + std::string(l_ex.what()));
+    }
+    return l_errorInfo;
+}
 } // namespace vpd