xref: /openbmc/openpower-vpd-parser/vpd-manager/src/event_logger.cpp (revision ca9a08665677fbd0b97654318805a6c92bb12ef8)
1 #include "config.h"
2 
3 #include "event_logger.hpp"
4 
5 #include "exceptions.hpp"
6 #include "logger.hpp"
7 
8 #include <systemd/sd-bus.h>
9 
10 #include <utility/json_utility.hpp>
11 #include <utility/vpd_specific_utility.hpp>
12 
13 #include <filesystem>
14 
15 namespace vpd
16 {
17 const std::unordered_map<types::SeverityType, std::string>
18     EventLogger::m_severityMap = {
19         {types::SeverityType::Notice,
20          "xyz.openbmc_project.Logging.Entry.Level.Notice"},
21         {types::SeverityType::Informational,
22          "xyz.openbmc_project.Logging.Entry.Level.Informational"},
23         {types::SeverityType::Debug,
24          "xyz.openbmc_project.Logging.Entry.Level.Debug"},
25         {types::SeverityType::Warning,
26          "xyz.openbmc_project.Logging.Entry.Level.Warning"},
27         {types::SeverityType::Critical,
28          "xyz.openbmc_project.Logging.Entry.Level.Critical"},
29         {types::SeverityType::Emergency,
30          "xyz.openbmc_project.Logging.Entry.Level.Emergency"},
31         {types::SeverityType::Alert,
32          "xyz.openbmc_project.Logging.Entry.Level.Alert"},
33         {types::SeverityType::Error,
34          "xyz.openbmc_project.Logging.Entry.Level.Error"}};
35 
36 const std::unordered_map<types::ErrorType, std::string>
37     EventLogger::m_errorMsgMap = {
38         {types::ErrorType::DefaultValue, "com.ibm.VPD.Error.DefaultValue"},
39         {types::ErrorType::UndefinedError, "com.ibm.VPD.Error.UndefinedError"},
40         {types::ErrorType::InvalidVpdMessage, "com.ibm.VPD.Error.InvalidVPD"},
41         {types::ErrorType::VpdMismatch, "com.ibm.VPD.Error.Mismatch"},
42         {types::ErrorType::InvalidEeprom,
43          "com.ibm.VPD.Error.InvalidEepromPath"},
44         {types::ErrorType::EccCheckFailed, "com.ibm.VPD.Error.EccCheckFailed"},
45         {types::ErrorType::JsonFailure, "com.ibm.VPD.Error.InvalidJson"},
46         {types::ErrorType::DbusFailure, "com.ibm.VPD.Error.DbusFailure"},
47         {types::ErrorType::InvalidSystem,
48          "com.ibm.VPD.Error.UnknownSystemType"},
49         {types::ErrorType::EssentialFru,
50          "com.ibm.VPD.Error.RequiredFRUMissing"},
51         {types::ErrorType::GpioError, "com.ibm.VPD.Error.GPIOError"},
52         {types::ErrorType::InternalFailure,
53          "xyz.openbmc_project.Common.Error.InternalFailure"},
54         {types::ErrorType::FruMissing, "com.ibm.VPD.Error.RequiredFRUMissing"},
55         {types::ErrorType::SystemTypeMismatch,
56          "com.ibm.VPD.Error.SystemTypeMismatch"},
57         {types::ErrorType::UnknownSystemSettings,
58          "com.ibm.VPD.Error.UnknownSystemSettings"},
59         {types::ErrorType::FirmwareError, "com.ibm.VPD.Error.FirmwareError"},
60         {types::ErrorType::VpdParseError, "com.ibm.VPD.Error.VPDParseError"}};
61 
62 const std::unordered_map<types::CalloutPriority, std::string>
63     EventLogger::m_priorityMap = {
64         {types::CalloutPriority::High, "H"},
65         {types::CalloutPriority::Medium, "M"},
66         {types::CalloutPriority::MediumGroupA, "A"},
67         {types::CalloutPriority::MediumGroupB, "B"},
68         {types::CalloutPriority::MediumGroupC, "C"},
69         {types::CalloutPriority::Low, "L"}};
70 
createAsyncPelWithInventoryCallout(const types::ErrorType & i_errorType,const types::SeverityType & i_severity,const std::vector<types::InventoryCalloutData> & i_callouts,const std::string & i_fileName,const std::string & i_funcName,const uint8_t i_internalRc,const std::string & i_description,const std::optional<std::string> i_userData1,const std::optional<std::string> i_userData2,const std::optional<std::string> i_symFru,const std::optional<std::string> i_procedure)71 void EventLogger::createAsyncPelWithInventoryCallout(
72     const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
73     const std::vector<types::InventoryCalloutData>& i_callouts,
74     const std::string& i_fileName, const std::string& i_funcName,
75     const uint8_t i_internalRc, const std::string& i_description,
76     const std::optional<std::string> i_userData1,
77     const std::optional<std::string> i_userData2,
78     const std::optional<std::string> i_symFru,
79     const std::optional<std::string> i_procedure)
80 {
81     (void)i_symFru;
82     (void)i_procedure;
83 
84     try
85     {
86         if (i_callouts.empty())
87         {
88             logging::logMessage("Callout information is missing to create PEL");
89             // TODO: Revisit this instead of simpley returning.
90             return;
91         }
92 
93         if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
94         {
95             throw std::runtime_error(
96                 "Error type not found in the error message map to create PEL");
97             // TODO: Need to handle, instead of throwing exception. Create
98             // default message in message_registry.json.
99         }
100 
101         const std::string& l_message = m_errorMsgMap.at(i_errorType);
102 
103         const std::string& l_severity =
104             (m_severityMap.find(i_severity) != m_severityMap.end()
105                  ? m_severityMap.at(i_severity)
106                  : m_severityMap.at(types::SeverityType::Informational));
107 
108         std::string l_description =
109             (!i_description.empty() ? i_description : "VPD generic error");
110 
111         std::string l_userData1 = (i_userData1) ? (*i_userData1) : "";
112 
113         std::string l_userData2 = (i_userData2) ? (*i_userData2) : "";
114 
115         const types::InventoryCalloutData& l_invCallout = i_callouts[0];
116         // TODO: Need to handle multiple inventory path callout's, when multiple
117         // callout's is supported by "Logging" service.
118 
119         const types::CalloutPriority& l_priorityEnum = get<1>(l_invCallout);
120 
121         const std::string& l_priority =
122             (m_priorityMap.find(l_priorityEnum) != m_priorityMap.end()
123                  ? m_priorityMap.at(l_priorityEnum)
124                  : m_priorityMap.at(types::CalloutPriority::Low));
125 
126         sd_bus* l_sdBus = nullptr;
127         sd_bus_default(&l_sdBus);
128 
129         const uint8_t l_additionalDataCount = 8;
130         auto l_rc = sd_bus_call_method_async(
131             l_sdBus, NULL, constants::eventLoggingServiceName,
132             constants::eventLoggingObjectPath, constants::eventLoggingInterface,
133             "Create", NULL, NULL, "ssa{ss}", l_message.c_str(),
134             l_severity.c_str(), l_additionalDataCount, "FileName",
135             i_fileName.c_str(), "FunctionName", i_funcName.c_str(),
136             "InternalRc", std::to_string(i_internalRc).c_str(), "DESCRIPTION",
137             l_description.c_str(), "UserData1", l_userData1.c_str(),
138             "UserData2", l_userData2.c_str(), "CALLOUT_INVENTORY_PATH",
139             get<0>(l_invCallout).c_str(), "CALLOUT_PRIORITY",
140             l_priority.c_str());
141 
142         if (l_rc < 0)
143         {
144             logging::logMessage(
145                 "Error calling sd_bus_call_method_async, Message = " +
146                 std::string(strerror(-l_rc)));
147         }
148     }
149     catch (const std::exception& l_ex)
150     {
151         logging::logMessage(
152             "Create PEL failed with error: " + std::string(l_ex.what()));
153     }
154 }
155 
createAsyncPelWithI2cDeviceCallout(const types::ErrorType i_errorType,const types::SeverityType i_severity,const std::vector<types::DeviceCalloutData> & i_callouts,const std::string & i_fileName,const std::string & i_funcName,const uint8_t i_internalRc,const std::optional<std::pair<std::string,std::string>> i_userData1,const std::optional<std::pair<std::string,std::string>> i_userData2)156 void EventLogger::createAsyncPelWithI2cDeviceCallout(
157     const types::ErrorType i_errorType, const types::SeverityType i_severity,
158     const std::vector<types::DeviceCalloutData>& i_callouts,
159     const std::string& i_fileName, const std::string& i_funcName,
160     const uint8_t i_internalRc,
161     const std::optional<std::pair<std::string, std::string>> i_userData1,
162     const std::optional<std::pair<std::string, std::string>> i_userData2)
163 {
164     // TODO, implementation needs to be added.
165     (void)i_errorType;
166     (void)i_severity;
167     (void)i_callouts;
168     (void)i_fileName;
169     (void)i_funcName;
170     (void)i_internalRc;
171     (void)i_userData1;
172     (void)i_userData2;
173 }
174 
createAsyncPelWithI2cBusCallout(const types::ErrorType i_errorType,const types::SeverityType i_severity,const std::vector<types::I2cBusCalloutData> & i_callouts,const std::string & i_fileName,const std::string & i_funcName,const uint8_t i_internalRc,const std::optional<std::pair<std::string,std::string>> i_userData1,const std::optional<std::pair<std::string,std::string>> i_userData2)175 void EventLogger::createAsyncPelWithI2cBusCallout(
176     const types::ErrorType i_errorType, const types::SeverityType i_severity,
177     const std::vector<types::I2cBusCalloutData>& i_callouts,
178     const std::string& i_fileName, const std::string& i_funcName,
179     const uint8_t i_internalRc,
180     const std::optional<std::pair<std::string, std::string>> i_userData1,
181     const std::optional<std::pair<std::string, std::string>> i_userData2)
182 {
183     // TODO, implementation needs to be added.
184     (void)i_errorType;
185     (void)i_severity;
186     (void)i_callouts;
187     (void)i_fileName;
188     (void)i_funcName;
189     (void)i_internalRc;
190     (void)i_userData1;
191     (void)i_userData2;
192 }
193 
createAsyncPel(const types::ErrorType & i_errorType,const types::SeverityType & i_severity,const std::string & i_fileName,const std::string & i_funcName,const uint8_t i_internalRc,const std::string & i_description,const std::optional<std::string> i_userData1,const std::optional<std::string> i_userData2,const std::optional<std::string> i_symFru,const std::optional<std::string> i_procedure)194 void EventLogger::createAsyncPel(
195     const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
196     const std::string& i_fileName, const std::string& i_funcName,
197     const uint8_t i_internalRc, const std::string& i_description,
198     const std::optional<std::string> i_userData1,
199     const std::optional<std::string> i_userData2,
200     const std::optional<std::string> i_symFru,
201     const std::optional<std::string> i_procedure)
202 {
203     (void)i_symFru;
204     (void)i_procedure;
205     try
206     {
207         if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
208         {
209             throw std::runtime_error("Unsupported error type received");
210             // TODO: Need to handle, instead of throwing an exception.
211         }
212 
213         const std::string& l_message = m_errorMsgMap.at(i_errorType);
214 
215         const std::string& l_severity =
216             (m_severityMap.find(i_severity) != m_severityMap.end()
217                  ? m_severityMap.at(i_severity)
218                  : m_severityMap.at(types::SeverityType::Informational));
219 
220         const std::string l_description =
221             ((!i_description.empty() ? i_description : "VPD generic error"));
222 
223         const std::string l_userData1 = ((i_userData1) ? (*i_userData1) : "");
224 
225         const std::string l_userData2 = ((i_userData2) ? (*i_userData2) : "");
226 
227         sd_bus* l_sdBus = nullptr;
228         sd_bus_default(&l_sdBus);
229 
230         // VALUE_6 represents the additional data pair count passing to create
231         // PEL. If there any change in additional data, we need to pass the
232         // correct number.
233         auto l_rc = sd_bus_call_method_async(
234             l_sdBus, NULL, constants::eventLoggingServiceName,
235             constants::eventLoggingObjectPath, constants::eventLoggingInterface,
236             "Create", NULL, NULL, "ssa{ss}", l_message.c_str(),
237             l_severity.c_str(), constants::VALUE_6, "FileName",
238             i_fileName.c_str(), "FunctionName", i_funcName.c_str(),
239             "InternalRc", std::to_string(i_internalRc).c_str(), "DESCRIPTION",
240             l_description.c_str(), "UserData1", l_userData1.c_str(),
241             "UserData2", l_userData2.c_str());
242 
243         if (l_rc < 0)
244         {
245             logging::logMessage(
246                 "Error calling sd_bus_call_method_async, Message = " +
247                 std::string(strerror(-l_rc)));
248         }
249     }
250     catch (const sdbusplus::exception::SdBusError& l_ex)
251     {
252         logging::logMessage("Async PEL creation failed with an error: " +
253                             std::string(l_ex.what()));
254     }
255 }
256 
createSyncPel(const types::ErrorType & i_errorType,const types::SeverityType & i_severity,const std::string & i_fileName,const std::string & i_funcName,const uint8_t i_internalRc,const std::string & i_description,const std::optional<std::string> i_userData1,const std::optional<std::string> i_userData2,const std::optional<std::string> i_symFru,const std::optional<std::string> i_procedure)257 void EventLogger::createSyncPel(
258     const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
259     const std::string& i_fileName, const std::string& i_funcName,
260     const uint8_t i_internalRc, const std::string& i_description,
261     const std::optional<std::string> i_userData1,
262     const std::optional<std::string> i_userData2,
263     const std::optional<std::string> i_symFru,
264     const std::optional<std::string> i_procedure)
265 {
266     (void)i_symFru;
267     (void)i_procedure;
268     try
269     {
270         if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
271         {
272             throw std::runtime_error("Unsupported error type received");
273             // TODO: Need to handle, instead of throwing an exception.
274         }
275 
276         const std::string& l_message = m_errorMsgMap.at(i_errorType);
277 
278         const std::string& l_severity =
279             (m_severityMap.find(i_severity) != m_severityMap.end()
280                  ? m_severityMap.at(i_severity)
281                  : m_severityMap.at(types::SeverityType::Informational));
282 
283         const std::string l_description =
284             ((!i_description.empty() ? i_description : "VPD generic error"));
285 
286         const std::string l_userData1 = ((i_userData1) ? (*i_userData1) : "");
287 
288         const std::string l_userData2 = ((i_userData2) ? (*i_userData2) : "");
289 
290         std::map<std::string, std::string> l_additionalData{
291             {"FileName", i_fileName},
292             {"FunctionName", i_funcName},
293             {"DESCRIPTION", l_description},
294             {"InteranlRc", std::to_string(i_internalRc)},
295             {"UserData1", l_userData1.c_str()},
296             {"UserData2", l_userData2.c_str()}};
297 
298         auto l_bus = sdbusplus::bus::new_default();
299         auto l_method =
300             l_bus.new_method_call(constants::eventLoggingServiceName,
301                                   constants::eventLoggingObjectPath,
302                                   constants::eventLoggingInterface, "Create");
303         l_method.append(l_message, l_severity, l_additionalData);
304         l_bus.call(l_method);
305     }
306     catch (const sdbusplus::exception::SdBusError& l_ex)
307     {
308         logging::logMessage("Sync PEL creation failed with an error: " +
309                             std::string(l_ex.what()));
310     }
311 }
312 
createSyncPelWithInvCallOut(const types::ErrorType & i_errorType,const types::SeverityType & i_severity,const std::string & i_fileName,const std::string & i_funcName,const uint8_t i_internalRc,const std::string & i_description,const std::vector<types::InventoryCalloutData> & i_callouts,const std::optional<std::string> i_userData1,const std::optional<std::string> i_userData2,const std::optional<std::string> i_symFru,const std::optional<std::string> i_procedure)313 void EventLogger::createSyncPelWithInvCallOut(
314     const types::ErrorType& i_errorType, const types::SeverityType& i_severity,
315     const std::string& i_fileName, const std::string& i_funcName,
316     const uint8_t i_internalRc, const std::string& i_description,
317     const std::vector<types::InventoryCalloutData>& i_callouts,
318     const std::optional<std::string> i_userData1,
319     const std::optional<std::string> i_userData2,
320     [[maybe_unused]] const std::optional<std::string> i_symFru,
321     [[maybe_unused]] const std::optional<std::string> i_procedure)
322 {
323     try
324     {
325         if (i_callouts.empty())
326         {
327             createSyncPel(i_errorType, i_severity, i_fileName, i_funcName,
328                           i_internalRc, i_description, i_userData1, i_userData2,
329                           i_symFru, i_procedure);
330             logging::logMessage(
331                 "Callout list is empty, creating PEL without call out");
332             return;
333         }
334 
335         if (m_errorMsgMap.find(i_errorType) == m_errorMsgMap.end())
336         {
337             throw std::runtime_error("Unsupported error type received");
338         }
339 
340         // Path to hold callout inventory path.
341         std::string l_calloutInvPath;
342 
343         uint16_t l_errCode = 0;
344 
345         // check if callout path is a valid inventory path. if not, get the JSON
346         // object to get inventory path.
347         if (std::get<0>(i_callouts[0])
348                 .compare(constants::VALUE_0, strlen(constants::pimPath),
349                          constants::pimPath) != constants::STR_CMP_SUCCESS)
350         {
351             std::error_code l_ec;
352             // implies json dependent execution.
353             if (std::filesystem::exists(INVENTORY_JSON_SYM_LINK, l_ec))
354             {
355                 if (!l_ec)
356                 {
357                     nlohmann::json l_parsedJson = jsonUtility::getParsedJson(
358                         INVENTORY_JSON_SYM_LINK, l_errCode);
359 
360                     if (l_errCode)
361                     {
362                         logging::logMessage(
363                             "Failed to parse JSON file [ " +
364                             std::string(INVENTORY_JSON_SYM_LINK) +
365                             " ], error : " +
366                             vpdSpecificUtility::getErrCodeMsg(l_errCode));
367                     }
368 
369                     l_calloutInvPath = jsonUtility::getInventoryObjPathFromJson(
370                         l_parsedJson, std::get<0>(i_callouts[0]), l_errCode);
371                 }
372                 else
373                 {
374                     logging::logMessage(
375                         "Error finding symlink. Continue with given path");
376                 }
377             }
378         }
379 
380         if (l_calloutInvPath.empty())
381         {
382             l_calloutInvPath = std::get<0>(i_callouts[0]);
383 
384             if (l_errCode)
385             {
386                 logging::logMessage(
387                     "Failed to get inventory object path from JSON for FRU [" +
388                     std::get<0>(i_callouts[0]) + "], error : " +
389                     vpdSpecificUtility::getErrCodeMsg(l_errCode));
390             }
391         }
392 
393         const std::map<std::string, std::string> l_additionalData{
394             {"FileName", i_fileName},
395             {"FunctionName", i_funcName},
396             {"DESCRIPTION",
397              (!i_description.empty() ? i_description : "VPD generic error")},
398             {"CALLOUT_INVENTORY_PATH", l_calloutInvPath},
399             {"InteranlRc", std::to_string(i_internalRc)},
400             {"UserData1", ((i_userData1) ? (*i_userData1) : "").c_str()},
401             {"UserData2", ((i_userData2) ? (*i_userData2) : "").c_str()}};
402 
403         const std::string& l_severity =
404             (m_severityMap.find(i_severity) != m_severityMap.end()
405                  ? m_severityMap.at(i_severity)
406                  : m_severityMap.at(types::SeverityType::Informational));
407 
408         auto l_bus = sdbusplus::bus::new_default();
409         auto l_method =
410             l_bus.new_method_call(constants::eventLoggingServiceName,
411                                   constants::eventLoggingObjectPath,
412                                   constants::eventLoggingInterface, "Create");
413         l_method.append(m_errorMsgMap.at(i_errorType), l_severity,
414                         l_additionalData);
415         l_bus.call(l_method);
416     }
417     catch (const std::exception& l_ex)
418     {
419         logging::logMessage(
420             "Sync PEL creation with inventory path failed with error: " +
421             std::string(l_ex.what()));
422     }
423 }
424 
getExceptionData(const std::exception & i_exception)425 types::ExceptionDataMap EventLogger::getExceptionData(
426     const std::exception& i_exception)
427 {
428     types::ExceptionDataMap l_errorInfo{
429         {"ErrorType", types::ErrorType::UndefinedError},
430         {"ErrorMsg", i_exception.what()}};
431 
432     try
433     {
434         if (typeid(i_exception) == typeid(DataException))
435         {
436             const DataException& l_ex =
437                 dynamic_cast<const DataException&>(i_exception);
438             l_errorInfo["ErrorType"] = l_ex.getErrorType();
439             l_errorInfo["ErrorMsg"] =
440                 std::string("Data Exception. Reason: ") + i_exception.what();
441         }
442         else if (typeid(i_exception) == typeid(EccException))
443         {
444             const EccException& l_ex =
445                 dynamic_cast<const EccException&>(i_exception);
446             l_errorInfo["ErrorType"] = l_ex.getErrorType();
447             l_errorInfo["ErrorMsg"] =
448                 std::string("Ecc Exception. Reason: ") + i_exception.what();
449         }
450         else if (typeid(i_exception) == typeid(JsonException))
451         {
452             const JsonException& l_ex =
453                 dynamic_cast<const JsonException&>(i_exception);
454             l_errorInfo["ErrorType"] = l_ex.getErrorType();
455             l_errorInfo["ErrorMsg"] =
456                 std::string("Json Exception. Reason: ") + i_exception.what();
457         }
458         else if (typeid(i_exception) == typeid(GpioException))
459         {
460             const GpioException& l_ex =
461                 dynamic_cast<const GpioException&>(i_exception);
462             l_errorInfo["ErrorType"] = l_ex.getErrorType();
463             l_errorInfo["ErrorMsg"] =
464                 std::string("Gpio Exception. Reason: ") + i_exception.what();
465         }
466         else if (typeid(i_exception) == typeid(DbusException))
467         {
468             const DbusException& l_ex =
469                 dynamic_cast<const DbusException&>(i_exception);
470             l_errorInfo["ErrorType"] = l_ex.getErrorType();
471             l_errorInfo["ErrorMsg"] =
472                 std::string("Dbus Exception. Reason: ") + i_exception.what();
473         }
474         else if (typeid(i_exception) == typeid(FirmwareException))
475         {
476             const FirmwareException& l_ex =
477                 dynamic_cast<const FirmwareException&>(i_exception);
478             l_errorInfo["ErrorType"] = l_ex.getErrorType();
479             l_errorInfo["ErrorMsg"] =
480                 std::string("Firmware Exception. Reason: ") +
481                 i_exception.what();
482         }
483         else if (typeid(i_exception) == typeid(EepromException))
484         {
485             const EepromException& l_ex =
486                 dynamic_cast<const EepromException&>(i_exception);
487             l_errorInfo["ErrorType"] = l_ex.getErrorType();
488             l_errorInfo["ErrorMsg"] =
489                 std::string("Eeprom Exception. Reason: ") + i_exception.what();
490         }
491         else if (typeid(i_exception) == typeid(std::runtime_error))
492         {
493             // Since it is a standard exception no casting is required and error
494             // type is hardcoded.
495             l_errorInfo["ErrorType"] = types::ErrorType::FirmwareError;
496             l_errorInfo["ErrorMsg"] =
497                 std::string("Standard runtime exception. Reason: ") +
498                 i_exception.what();
499         }
500     }
501     catch (const std::exception& l_ex)
502     {
503         logging::logMessage(
504             "Failed to get error info, reason: " + std::string(l_ex.what()));
505     }
506     return l_errorInfo;
507 }
508 
getErrorType(const std::exception & i_exception)509 types::ErrorType EventLogger::getErrorType(const std::exception& i_exception)
510 {
511     const auto& l_exceptionDataMap = getExceptionData(i_exception);
512 
513     auto l_itrToErrType = l_exceptionDataMap.find("ErrorType");
514     if (l_itrToErrType == l_exceptionDataMap.end())
515     {
516         return types::ErrorType::UndefinedError;
517     }
518 
519     auto l_ptrToErrType =
520         std::get_if<types::ErrorType>(&l_itrToErrType->second);
521     if (!l_ptrToErrType)
522     {
523         return types::ErrorType::UndefinedError;
524     }
525 
526     return *l_ptrToErrType;
527 }
528 
getErrorMsg(const std::exception & i_exception)529 std::string EventLogger::getErrorMsg(const std::exception& i_exception)
530 {
531     const auto& l_exceptionDataMap = getExceptionData(i_exception);
532 
533     auto l_itrToErrMsg = l_exceptionDataMap.find("ErrorMsg");
534     if (l_itrToErrMsg == l_exceptionDataMap.end())
535     {
536         return i_exception.what();
537     }
538 
539     auto l_ptrToErrMsg = std::get_if<std::string>(&l_itrToErrMsg->second);
540     if (!l_ptrToErrMsg)
541     {
542         return i_exception.what();
543     }
544 
545     return *l_ptrToErrMsg;
546 }
547 
getErrorTypeString(const types::ErrorType & i_errorType)548 std::string EventLogger::getErrorTypeString(
549     const types::ErrorType& i_errorType) noexcept
550 {
551     const auto l_entry = m_errorMsgMap.find(i_errorType);
552     return (l_entry != m_errorMsgMap.end()
553                 ? l_entry->second
554                 : m_errorMsgMap.at(types::ErrorType::UndefinedError));
555 }
556 } // namespace vpd
557