blob: a9ba0771f04999a4804aa45cfaf2383b829d5901 [file] [log] [blame]
Sunny Srivastava6046c372025-06-06 12:13:19 +05301#include "config.h"
2
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -05003#include "event_logger.hpp"
4
Anupama B Rb53d97c2025-02-24 03:37:34 -06005#include "exceptions.hpp"
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -05006#include "logger.hpp"
7
8#include <systemd/sd-bus.h>
9
Sunny Srivastava6046c372025-06-06 12:13:19 +053010#include <utility/json_utility.hpp>
Rekha Aparna017567a2025-08-13 02:07:06 -050011#include <utility/vpd_specific_utility.hpp>
Sunny Srivastava6046c372025-06-06 12:13:19 +053012
13#include <filesystem>
14
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050015namespace vpd
16{
17const 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
36const std::unordered_map<types::ErrorType, std::string>
37 EventLogger::m_errorMsgMap = {
38 {types::ErrorType::DefaultValue, "com.ibm.VPD.Error.DefaultValue"},
Sunny Srivastavac09e2102025-04-23 10:47:06 +053039 {types::ErrorType::UndefinedError, "com.ibm.VPD.Error.UndefinedError"},
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050040 {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"},
Sunny Srivastavaa88a2982025-01-23 12:03:21 +053051 {types::ErrorType::GpioError, "com.ibm.VPD.Error.GPIOError"},
52 {types::ErrorType::InternalFailure,
53 "xyz.openbmc_project.Common.Error.InternalFailure"},
Rekha Aparnaffdff312025-03-25 01:10:56 -050054 {types::ErrorType::FruMissing, "com.ibm.VPD.Error.RequiredFRUMissing"},
55 {types::ErrorType::SystemTypeMismatch,
56 "com.ibm.VPD.Error.SystemTypeMismatch"},
57 {types::ErrorType::UnknownSystemSettings,
Sunny Srivastava4fa796c2025-04-01 10:27:02 +053058 "com.ibm.VPD.Error.UnknownSystemSettings"},
Rekha Aparna10a6ac92025-06-12 23:34:41 -050059 {types::ErrorType::FirmwareError, "com.ibm.VPD.Error.FirmwareError"},
60 {types::ErrorType::VpdParseError, "com.ibm.VPD.Error.VPDParseError"}};
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050061
62const 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
71void 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
156void 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
175void 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
194void 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
257void 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}
Anupama B Rb53d97c2025-02-24 03:37:34 -0600312
Sunny Srivastava6046c372025-06-06 12:13:19 +0530313void 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
Rekha Aparna017567a2025-08-13 02:07:06 -0500343 uint16_t l_errCode = 0;
344
Sunny Srivastava6046c372025-06-06 12:13:19 +0530345 // 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 l_calloutInvPath = jsonUtility::getInventoryObjPathFromJson(
358 jsonUtility::getParsedJson(INVENTORY_JSON_SYM_LINK),
Rekha Aparna017567a2025-08-13 02:07:06 -0500359 std::get<0>(i_callouts[0]), l_errCode);
Sunny Srivastava6046c372025-06-06 12:13:19 +0530360 }
361 else
362 {
363 logging::logMessage(
364 "Error finding symlink. Continue with given path");
365 }
366 }
367 }
368
369 if (l_calloutInvPath.empty())
370 {
371 l_calloutInvPath = std::get<0>(i_callouts[0]);
Rekha Aparna017567a2025-08-13 02:07:06 -0500372
373 if (l_errCode)
374 {
375 logging::logMessage(
376 "Failed to get inventory object path from JSON for FRU [" +
377 std::get<0>(i_callouts[0]) + "], error : " +
378 vpdSpecificUtility::getErrCodeMsg(l_errCode));
379 }
Sunny Srivastava6046c372025-06-06 12:13:19 +0530380 }
381
382 const std::map<std::string, std::string> l_additionalData{
383 {"FileName", i_fileName},
384 {"FunctionName", i_funcName},
385 {"DESCRIPTION",
386 (!i_description.empty() ? i_description : "VPD generic error")},
387 {"CALLOUT_INVENTORY_PATH", l_calloutInvPath},
388 {"InteranlRc", std::to_string(i_internalRc)},
389 {"UserData1", ((i_userData1) ? (*i_userData1) : "").c_str()},
390 {"UserData2", ((i_userData2) ? (*i_userData2) : "").c_str()}};
391
392 const std::string& l_severity =
393 (m_severityMap.find(i_severity) != m_severityMap.end()
394 ? m_severityMap.at(i_severity)
395 : m_severityMap.at(types::SeverityType::Informational));
396
397 auto l_bus = sdbusplus::bus::new_default();
398 auto l_method =
399 l_bus.new_method_call(constants::eventLoggingServiceName,
400 constants::eventLoggingObjectPath,
401 constants::eventLoggingInterface, "Create");
402 l_method.append(m_errorMsgMap.at(i_errorType), l_severity,
403 l_additionalData);
404 l_bus.call(l_method);
405 }
406 catch (const std::exception& l_ex)
407 {
408 logging::logMessage(
409 "Sync PEL creation with inventory path failed with error: " +
410 std::string(l_ex.what()));
411 }
412}
413
Anupama B Rb53d97c2025-02-24 03:37:34 -0600414types::ExceptionDataMap EventLogger::getExceptionData(
415 const std::exception& i_exception)
416{
417 types::ExceptionDataMap l_errorInfo{
Sunny Srivastavac09e2102025-04-23 10:47:06 +0530418 {"ErrorType", types::ErrorType::UndefinedError},
Anupama B Rb53d97c2025-02-24 03:37:34 -0600419 {"ErrorMsg", i_exception.what()}};
420
421 try
422 {
423 if (typeid(i_exception) == typeid(DataException))
424 {
425 const DataException& l_ex =
426 dynamic_cast<const DataException&>(i_exception);
427 l_errorInfo["ErrorType"] = l_ex.getErrorType();
428 l_errorInfo["ErrorMsg"] =
429 std::string("Data Exception. Reason: ") + i_exception.what();
430 }
431 else if (typeid(i_exception) == typeid(EccException))
432 {
433 const EccException& l_ex =
434 dynamic_cast<const EccException&>(i_exception);
435 l_errorInfo["ErrorType"] = l_ex.getErrorType();
436 l_errorInfo["ErrorMsg"] =
437 std::string("Ecc Exception. Reason: ") + i_exception.what();
438 }
439 else if (typeid(i_exception) == typeid(JsonException))
440 {
441 const JsonException& l_ex =
442 dynamic_cast<const JsonException&>(i_exception);
443 l_errorInfo["ErrorType"] = l_ex.getErrorType();
444 l_errorInfo["ErrorMsg"] =
445 std::string("Json Exception. Reason: ") + i_exception.what();
446 }
447 else if (typeid(i_exception) == typeid(GpioException))
448 {
449 const GpioException& l_ex =
450 dynamic_cast<const GpioException&>(i_exception);
451 l_errorInfo["ErrorType"] = l_ex.getErrorType();
452 l_errorInfo["ErrorMsg"] =
453 std::string("Gpio Exception. Reason: ") + i_exception.what();
454 }
455 else if (typeid(i_exception) == typeid(DbusException))
456 {
457 const DbusException& l_ex =
458 dynamic_cast<const DbusException&>(i_exception);
459 l_errorInfo["ErrorType"] = l_ex.getErrorType();
460 l_errorInfo["ErrorMsg"] =
461 std::string("Dbus Exception. Reason: ") + i_exception.what();
462 }
463 else if (typeid(i_exception) == typeid(FirmwareException))
464 {
465 const FirmwareException& l_ex =
466 dynamic_cast<const FirmwareException&>(i_exception);
467 l_errorInfo["ErrorType"] = l_ex.getErrorType();
468 l_errorInfo["ErrorMsg"] =
469 std::string("Firmware Exception. Reason: ") +
470 i_exception.what();
471 }
472 else if (typeid(i_exception) == typeid(EepromException))
473 {
474 const EepromException& l_ex =
475 dynamic_cast<const EepromException&>(i_exception);
476 l_errorInfo["ErrorType"] = l_ex.getErrorType();
477 l_errorInfo["ErrorMsg"] =
478 std::string("Eeprom Exception. Reason: ") + i_exception.what();
479 }
Sunny Srivastavac09e2102025-04-23 10:47:06 +0530480 else if (typeid(i_exception) == typeid(std::runtime_error))
481 {
482 // Since it is a standard exception no casting is required and error
483 // type is hardcoded.
484 l_errorInfo["ErrorType"] = types::ErrorType::FirmwareError;
485 l_errorInfo["ErrorMsg"] =
Souvik Roy37c6bef2025-07-17 00:55:59 -0500486 std::string("Standard runtime exception. Reason: ") +
487 i_exception.what();
Sunny Srivastavac09e2102025-04-23 10:47:06 +0530488 }
Anupama B Rb53d97c2025-02-24 03:37:34 -0600489 }
490 catch (const std::exception& l_ex)
491 {
492 logging::logMessage(
493 "Failed to get error info, reason: " + std::string(l_ex.what()));
494 }
495 return l_errorInfo;
496}
Sunny Srivastava15a189a2025-02-26 16:53:19 +0530497
498types::ErrorType EventLogger::getErrorType(const std::exception& i_exception)
499{
500 const auto& l_exceptionDataMap = getExceptionData(i_exception);
501
502 auto l_itrToErrType = l_exceptionDataMap.find("ErrorType");
503 if (l_itrToErrType == l_exceptionDataMap.end())
504 {
Sunny Srivastavac09e2102025-04-23 10:47:06 +0530505 return types::ErrorType::UndefinedError;
Sunny Srivastava15a189a2025-02-26 16:53:19 +0530506 }
507
508 auto l_ptrToErrType =
509 std::get_if<types::ErrorType>(&l_itrToErrType->second);
510 if (!l_ptrToErrType)
511 {
Sunny Srivastavac09e2102025-04-23 10:47:06 +0530512 return types::ErrorType::UndefinedError;
Sunny Srivastava15a189a2025-02-26 16:53:19 +0530513 }
514
515 return *l_ptrToErrType;
516}
517
518std::string EventLogger::getErrorMsg(const std::exception& i_exception)
519{
520 const auto& l_exceptionDataMap = getExceptionData(i_exception);
521
522 auto l_itrToErrMsg = l_exceptionDataMap.find("ErrorMsg");
523 if (l_itrToErrMsg == l_exceptionDataMap.end())
524 {
525 return i_exception.what();
526 }
527
528 auto l_ptrToErrMsg = std::get_if<std::string>(&l_itrToErrMsg->second);
529 if (!l_ptrToErrMsg)
530 {
531 return i_exception.what();
532 }
533
534 return *l_ptrToErrMsg;
535}
Souvik Roy612bce82025-04-16 02:22:33 -0500536
537std::string EventLogger::getErrorTypeString(
538 const types::ErrorType& i_errorType) noexcept
539{
540 const auto l_entry = m_errorMsgMap.find(i_errorType);
541 return (l_entry != m_errorMsgMap.end()
542 ? l_entry->second
543 : m_errorMsgMap.at(types::ErrorType::UndefinedError));
544}
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500545} // namespace vpd