Error code handling in processing specific tags
The change implements error code to handle failure while processing some
of the JSON tags.
Going forward, error code will be used by the caller to identify the
type of failure that occurred while processing the tags and based
on that appropriate action will be taken.
Change-Id: I95783836d8829f0d50459a26da37a2e4e21638f5
Signed-off-by: Sunny Srivastava <sunnsr25@in.ibm.com>
diff --git a/vpd-manager/include/error_codes.hpp b/vpd-manager/include/error_codes.hpp
index ad436c4..204b96a 100644
--- a/vpd-manager/include/error_codes.hpp
+++ b/vpd-manager/include/error_codes.hpp
@@ -18,9 +18,13 @@
static constexpr auto MISSING_ACTION_TAG = 2003;
static constexpr auto FRU_PATH_NOT_FOUND = 2004;
static constexpr auto JSON_PARSE_ERROR = 2005;
+static constexpr auto JSON_MISSING_GPIO_INFO = 2006;
// Generic errors.
static constexpr auto INVALID_INPUT_PARAMETER = 3001;
+static constexpr auto DEVICE_NOT_PRESENT = 2006;
+static constexpr auto DEVICE_PRESENCE_UNKNOWN = 2007;
+static constexpr auto GPIO_LINE_EXCEPTION = 2008;
const std::unordered_map<int, std::string> errorCodeMap = {
{FILE_NOT_FOUND, "File does not exist."},
@@ -33,6 +37,11 @@
{FRU_PATH_NOT_FOUND, "The FRU path is not found in the JSON."},
{JSON_PARSE_ERROR, "Error while parsing JSON file."},
{INVALID_INPUT_PARAMETER,
- "Either one of the input parameter is invalid or empty."}};
+ "Either one of the input parameter is invalid or empty."},
+ {JSON_MISSING_GPIO_INFO, "JSON missing required GPIO info."},
+ {DEVICE_NOT_PRESENT,
+ "Presence pin read successfully but device was absent."},
+ {DEVICE_PRESENCE_UNKNOWN, "Exception on presence line GPIO."},
+ {GPIO_LINE_EXCEPTION, "There was an exception in GPIO line."}};
} // namespace error_code
} // namespace vpd
diff --git a/vpd-manager/include/utility/json_utility.hpp b/vpd-manager/include/utility/json_utility.hpp
index 74dfc38..c2bb646 100644
--- a/vpd-manager/include/utility/json_utility.hpp
+++ b/vpd-manager/include/utility/json_utility.hpp
@@ -21,26 +21,28 @@
{
// forward declaration of API for function map.
-bool processSystemCmdTag(const nlohmann::json& i_parsedConfigJson,
- const std::string& i_vpdFilePath,
- const std::string& i_baseAction,
- const std::string& i_flagToProcess);
+bool processSystemCmdTag(
+ const nlohmann::json& i_parsedConfigJson, const std::string& i_vpdFilePath,
+ const std::string& i_baseAction, const std::string& i_flagToProcess,
+ uint16_t& o_errCode);
// forward declaration of API for function map.
bool processGpioPresenceTag(
const nlohmann::json& i_parsedConfigJson, const std::string& i_vpdFilePath,
- const std::string& i_baseAction, const std::string& i_flagToProcess);
+ const std::string& i_baseAction, const std::string& i_flagToProcess,
+ uint16_t& o_errCode);
// forward declaration of API for function map.
bool procesSetGpioTag(const nlohmann::json& i_parsedConfigJson,
const std::string& i_vpdFilePath,
const std::string& i_baseAction,
- const std::string& i_flagToProcess);
+ const std::string& i_flagToProcess, uint16_t& o_errCode);
// Function pointers to process tags from config JSON.
typedef bool (*functionPtr)(
const nlohmann::json& i_parsedConfigJson, const std::string& i_vpdFilePath,
- const std::string& i_baseAction, const std::string& i_flagToProcess);
+ const std::string& i_baseAction, const std::string& i_flagToProcess,
+ uint16_t& o_errCode);
inline std::unordered_map<std::string, functionPtr> funcionMap{
{"gpioPresence", processGpioPresenceTag},
@@ -238,8 +240,16 @@
if (itrToFunction != funcionMap.end())
{
if (!itrToFunction->second(i_parsedConfigJson, i_vpdFilePath,
- "postFailAction", i_flagToProcess))
+ "postFailAction", i_flagToProcess,
+ o_errCode))
{
+ if (o_errCode)
+ {
+ logging::logMessage(
+ l_tags.key() + " failed for [" + i_vpdFilePath +
+ "]. Reason " +
+ vpdSpecificUtility::getErrCodeMsg(o_errCode));
+ }
return false;
}
}
@@ -259,47 +269,35 @@
* @param[in] i_baseAction - Base action for which this tag has been called.
* @param[in] i_flagToProcess - Flag nested under the base action for which this
* tag has been called.
+ * @param[out] o_errCode - To set error code in case of error.
* @return Execution status.
*/
inline bool processSystemCmdTag(
const nlohmann::json& i_parsedConfigJson, const std::string& i_vpdFilePath,
- const std::string& i_baseAction, const std::string& i_flagToProcess)
+ const std::string& i_baseAction, const std::string& i_flagToProcess,
+ uint16_t& o_errCode)
{
- try
+ if (i_vpdFilePath.empty() || i_parsedConfigJson.empty() ||
+ i_baseAction.empty() || i_flagToProcess.empty())
{
- if (i_vpdFilePath.empty() || i_parsedConfigJson.empty() ||
- i_baseAction.empty() || i_flagToProcess.empty())
- {
- throw std::runtime_error(
- std::string(__FUNCTION__) +
- " Invalid parameter. Abort processing of processSystemCmd.");
- }
-
- if (!((i_parsedConfigJson["frus"][i_vpdFilePath].at(
- 0)[i_baseAction][i_flagToProcess]["systemCmd"])
- .contains("cmd")))
- {
- throw JsonException(
- std::string(__FUNCTION__) +
- " Config JSON missing required information to execute system command for EEPROM " +
- i_vpdFilePath);
- }
-
- const std::string& l_systemCommand =
- i_parsedConfigJson["frus"][i_vpdFilePath].at(
- 0)[i_baseAction][i_flagToProcess]["systemCmd"]["cmd"];
-
- commonUtility::executeCmd(l_systemCommand);
- return true;
- }
- catch (const std::exception& l_ex)
- {
- EventLogger::createSyncPel(
- EventLogger::getErrorType(l_ex), types::SeverityType::Informational,
- __FILE__, __FUNCTION__, 0, EventLogger::getErrorMsg(l_ex),
- std::nullopt, std::nullopt, std::nullopt, std::nullopt);
+ o_errCode = error_code::INVALID_INPUT_PARAMETER;
return false;
}
+
+ if (!((i_parsedConfigJson["frus"][i_vpdFilePath].at(
+ 0)[i_baseAction][i_flagToProcess]["systemCmd"])
+ .contains("cmd")))
+ {
+ o_errCode = error_code::MISSING_FLAG;
+ return false;
+ }
+
+ const std::string& l_systemCommand =
+ i_parsedConfigJson["frus"][i_vpdFilePath].at(
+ 0)[i_baseAction][i_flagToProcess]["systemCmd"]["cmd"];
+
+ commonUtility::executeCmd(l_systemCommand);
+ return true;
}
/**
@@ -313,11 +311,13 @@
* @param[in] i_baseAction - Base action for which this tag has been called.
* @param[in] i_flagToProcess - Flag nested under the base action for which this
* tag has been called.
+ * @param[out] o_errCode - To set error code in case of error
* @return Execution status.
*/
inline bool processGpioPresenceTag(
const nlohmann::json& i_parsedConfigJson, const std::string& i_vpdFilePath,
- const std::string& i_baseAction, const std::string& i_flagToProcess)
+ const std::string& i_baseAction, const std::string& i_flagToProcess,
+ uint16_t& o_errCode)
{
std::string l_presencePinName;
try
@@ -325,9 +325,8 @@
if (i_vpdFilePath.empty() || i_parsedConfigJson.empty() ||
i_baseAction.empty() || i_flagToProcess.empty())
{
- throw std::runtime_error(
- std::string(__FUNCTION__) +
- "Invalid parameter. Abort processing of processGpioPresence tag");
+ o_errCode = error_code::INVALID_INPUT_PARAMETER;
+ return false;
}
if (!(((i_parsedConfigJson["frus"][i_vpdFilePath].at(
@@ -337,10 +336,8 @@
0)[i_baseAction][i_flagToProcess]["gpioPresence"])
.contains("value"))))
{
- throw JsonException(
- std::string(__FUNCTION__) +
- "Config JSON missing required information to detect presence for EEPROM " +
- i_vpdFilePath);
+ o_errCode = error_code::JSON_MISSING_GPIO_INFO;
+ return false;
}
// get the pin name
@@ -356,31 +353,26 @@
if (!l_presenceLine)
{
+ o_errCode = error_code::DEVICE_PRESENCE_UNKNOWN;
throw GpioException("Couldn't find the GPIO line.");
}
l_presenceLine.request({"Read the presence line",
gpiod::line_request::DIRECTION_INPUT, 0});
- return (l_presencePinValue == l_presenceLine.get_value());
- }
- catch (const std::exception& l_ex)
- {
- // No need to continue in case of JSON failure or Firmware error
- // as these are errors internal to the code and in that case the FRU
- // should not be processed. Any other error is considered as external
- // error in this case and a try to read the EEPROM should be done.
- if (EventLogger::getErrorType(l_ex) == types::ErrorType::JsonFailure ||
- EventLogger::getErrorType(l_ex) == types::ErrorType::FirmwareError)
+ if (l_presencePinValue != l_presenceLine.get_value())
{
- EventLogger::createSyncPel(
- EventLogger::getErrorType(l_ex),
- types::SeverityType::Informational, __FILE__, __FUNCTION__, 0,
- EventLogger::getErrorMsg(l_ex), std::nullopt, std::nullopt,
- std::nullopt, std::nullopt);
+ // As false is being returned in this case, caller needs to know
+ // that it is not due to some exception. It is because the pin was
+ // read correctly but was not having expected value.
+ o_errCode = error_code::DEVICE_NOT_PRESENT;
return false;
}
+ return true;
+ }
+ catch (const std::exception& l_ex)
+ {
std::string l_errMsg = "Exception on GPIO line: ";
l_errMsg += l_presencePinName;
l_errMsg += " Reason: ";
@@ -418,11 +410,13 @@
* @param[in] i_baseAction - Base action for which this tag has been called.
* @param[in] i_flagToProcess - Flag nested under the base action for which this
* tag has been called.
+ * @param[out] o_errCode - To set error code in case of error
* @return Execution status.
*/
inline bool procesSetGpioTag(
const nlohmann::json& i_parsedConfigJson, const std::string& i_vpdFilePath,
- const std::string& i_baseAction, const std::string& i_flagToProcess)
+ const std::string& i_baseAction, const std::string& i_flagToProcess,
+ uint16_t& o_errCode)
{
std::string l_pinName;
try
@@ -430,9 +424,8 @@
if (i_vpdFilePath.empty() || i_parsedConfigJson.empty() ||
i_baseAction.empty() || i_flagToProcess.empty())
{
- throw std::runtime_error(
- std::string(__FUNCTION__) +
- " Invalid parameter. Abort processing of procesSetGpio.");
+ o_errCode = error_code::INVALID_INPUT_PARAMETER;
+ return false;
}
if (!(((i_parsedConfigJson["frus"][i_vpdFilePath].at(
@@ -442,10 +435,8 @@
0)[i_baseAction][i_flagToProcess]["setGpio"])
.contains("value"))))
{
- throw JsonException(
- std::string(__FUNCTION__) +
- " Config JSON missing required information to set gpio line for EEPROM " +
- i_vpdFilePath);
+ o_errCode = error_code::JSON_MISSING_GPIO_INFO;
+ return false;
}
l_pinName = i_parsedConfigJson["frus"][i_vpdFilePath].at(
@@ -462,6 +453,7 @@
if (!l_outputLine)
{
+ o_errCode = error_code::GPIO_LINE_EXCEPTION;
throw GpioException("Couldn't find GPIO line.");
}
@@ -472,37 +464,25 @@
}
catch (const std::exception& l_ex)
{
- if (EventLogger::getErrorType(l_ex) != types::ErrorType::GpioError)
- {
- EventLogger::createSyncPel(
- EventLogger::getErrorType(l_ex),
- types::SeverityType::Informational, __FILE__, __FUNCTION__, 0,
- EventLogger::getErrorMsg(l_ex), std::nullopt, std::nullopt,
- std::nullopt, std::nullopt);
- }
- else
- {
- std::string l_errMsg = "Exception on GPIO line: ";
- l_errMsg += l_pinName;
- l_errMsg += " Reason: ";
- l_errMsg += l_ex.what();
- l_errMsg += " File: " + i_vpdFilePath + " Pel Logged";
+ std::string l_errMsg = "Exception on GPIO line: ";
+ l_errMsg += l_pinName;
+ l_errMsg += " Reason: ";
+ l_errMsg += l_ex.what();
+ l_errMsg += " File: " + i_vpdFilePath + " Pel Logged";
- uint16_t l_errCode = 0;
+ uint16_t l_errCode = 0;
- // ToDo -- Update Internal RC code
- EventLogger::createAsyncPelWithInventoryCallout(
- EventLogger::getErrorType(l_ex),
- types::SeverityType::Informational,
- {{getInventoryObjPathFromJson(i_parsedConfigJson, i_vpdFilePath,
- l_errCode),
- types::CalloutPriority::High}},
- std::source_location::current().file_name(),
- std::source_location::current().function_name(), 0, l_errMsg,
- std::nullopt, std::nullopt, std::nullopt, std::nullopt);
+ // ToDo -- Update Internal RC code
+ EventLogger::createAsyncPelWithInventoryCallout(
+ EventLogger::getErrorType(l_ex), types::SeverityType::Informational,
+ {{getInventoryObjPathFromJson(i_parsedConfigJson, i_vpdFilePath,
+ l_errCode),
+ types::CalloutPriority::High}},
+ std::source_location::current().file_name(),
+ std::source_location::current().function_name(), 0, l_errMsg,
+ std::nullopt, std::nullopt, std::nullopt, std::nullopt);
- logging::logMessage(l_errMsg);
- }
+ logging::logMessage(l_errMsg);
return false;
}
@@ -535,13 +515,11 @@
throw std::runtime_error(
std::string(__FUNCTION__) + " Invalid parameter");
}
-
if (!i_parsedConfigJson["frus"].contains(i_vpdFilePath))
{
throw JsonException(std::string(__FUNCTION__) + " File path: " +
i_vpdFilePath + " not found in JSON");
}
-
if (!i_parsedConfigJson["frus"][i_vpdFilePath].at(0).contains(i_action))
{
throw JsonException(
@@ -576,11 +554,19 @@
auto itrToFunction = funcionMap.find(l_tag.key());
if (itrToFunction != funcionMap.end())
{
+ uint16_t o_errCode = 0;
if (!itrToFunction->second(i_parsedConfigJson, i_vpdFilePath,
- i_action, i_flagToProcess))
+ i_action, i_flagToProcess, o_errCode))
{
// In case any of the tag fails to execute. Mark action
// as failed for that flag.
+ if (o_errCode)
+ {
+ logging::logMessage(
+ l_tag.key() + " failed for [" + i_vpdFilePath +
+ "]. Reason " +
+ vpdSpecificUtility::getErrCodeMsg(o_errCode));
+ }
return false;
}
}
diff --git a/vpd-manager/src/gpio_monitor.cpp b/vpd-manager/src/gpio_monitor.cpp
index d758c90..b155fac 100644
--- a/vpd-manager/src/gpio_monitor.cpp
+++ b/vpd-manager/src/gpio_monitor.cpp
@@ -81,9 +81,17 @@
return;
}
+ uint16_t l_errCode = 0;
bool l_currentPresencePinValue = jsonUtility::processGpioPresenceTag(
m_worker->getSysCfgJsonObj(), m_fruPath, "pollingRequired",
- "hotPlugging");
+ "hotPlugging", l_errCode);
+
+ if (l_errCode && l_errCode != error_code::DEVICE_NOT_PRESENT)
+ {
+ logging::logMessage("processGpioPresenceTag returned false for FRU [" +
+ m_fruPath + "] Due to error. Reason: " +
+ vpdSpecificUtility::getErrCodeMsg(l_errCode));
+ }
if (m_prevPresencePinValue != l_currentPresencePinValue)
{
@@ -101,9 +109,17 @@
void GpioEventHandler::setEventHandlerForGpioPresence(
const std::shared_ptr<boost::asio::io_context>& i_ioContext)
{
+ uint16_t l_errCode = 0;
m_prevPresencePinValue = jsonUtility::processGpioPresenceTag(
m_worker->getSysCfgJsonObj(), m_fruPath, "pollingRequired",
- "hotPlugging");
+ "hotPlugging", l_errCode);
+
+ if (l_errCode && l_errCode != error_code::DEVICE_NOT_PRESENT)
+ {
+ logging::logMessage("processGpioPresenceTag returned false for FRU [" +
+ m_fruPath + "] Due to error. Reason: " +
+ vpdSpecificUtility::getErrCodeMsg(l_errCode));
+ }
static std::vector<std::shared_ptr<boost::asio::steady_timer>> l_timers;