1*6c038f26SEd Tanous #include "error_message_utils.hpp"
2*6c038f26SEd Tanous
3*6c038f26SEd Tanous #include "logging.hpp"
4*6c038f26SEd Tanous
5*6c038f26SEd Tanous #include <nlohmann/json.hpp>
6*6c038f26SEd Tanous
7*6c038f26SEd Tanous #include <string>
8*6c038f26SEd Tanous #include <string_view>
9*6c038f26SEd Tanous
10*6c038f26SEd Tanous namespace redfish
11*6c038f26SEd Tanous {
12*6c038f26SEd Tanous
13*6c038f26SEd Tanous namespace messages
14*6c038f26SEd Tanous {
15*6c038f26SEd Tanous
addMessageToErrorJson(nlohmann::json & target,const nlohmann::json & message)16*6c038f26SEd Tanous void addMessageToErrorJson(nlohmann::json& target,
17*6c038f26SEd Tanous const nlohmann::json& message)
18*6c038f26SEd Tanous {
19*6c038f26SEd Tanous auto& error = target["error"];
20*6c038f26SEd Tanous
21*6c038f26SEd Tanous // If this is the first error message, fill in the information from the
22*6c038f26SEd Tanous // first error message to the top level struct
23*6c038f26SEd Tanous if (!error.is_object())
24*6c038f26SEd Tanous {
25*6c038f26SEd Tanous auto messageIdIterator = message.find("MessageId");
26*6c038f26SEd Tanous if (messageIdIterator == message.end())
27*6c038f26SEd Tanous {
28*6c038f26SEd Tanous BMCWEB_LOG_CRITICAL(
29*6c038f26SEd Tanous "Attempt to add error message without MessageId");
30*6c038f26SEd Tanous return;
31*6c038f26SEd Tanous }
32*6c038f26SEd Tanous
33*6c038f26SEd Tanous auto messageFieldIterator = message.find("Message");
34*6c038f26SEd Tanous if (messageFieldIterator == message.end())
35*6c038f26SEd Tanous {
36*6c038f26SEd Tanous BMCWEB_LOG_CRITICAL("Attempt to add error message without Message");
37*6c038f26SEd Tanous return;
38*6c038f26SEd Tanous }
39*6c038f26SEd Tanous error["code"] = *messageIdIterator;
40*6c038f26SEd Tanous error["message"] = *messageFieldIterator;
41*6c038f26SEd Tanous }
42*6c038f26SEd Tanous else
43*6c038f26SEd Tanous {
44*6c038f26SEd Tanous // More than 1 error occurred, so the message has to be generic
45*6c038f26SEd Tanous error["code"] = std::string(messageVersionPrefix) + "GeneralError";
46*6c038f26SEd Tanous error["message"] = "A general error has occurred. See Resolution for "
47*6c038f26SEd Tanous "information on how to resolve the error.";
48*6c038f26SEd Tanous }
49*6c038f26SEd Tanous
50*6c038f26SEd Tanous // This check could technically be done in the default construction
51*6c038f26SEd Tanous // branch above, but because we need the pointer to the extended info field
52*6c038f26SEd Tanous // anyway, it's more efficient to do it here.
53*6c038f26SEd Tanous auto& extendedInfo = error[messages::messageAnnotation];
54*6c038f26SEd Tanous if (!extendedInfo.is_array())
55*6c038f26SEd Tanous {
56*6c038f26SEd Tanous extendedInfo = nlohmann::json::array();
57*6c038f26SEd Tanous }
58*6c038f26SEd Tanous
59*6c038f26SEd Tanous extendedInfo.push_back(message);
60*6c038f26SEd Tanous }
61*6c038f26SEd Tanous
moveErrorsToErrorJson(nlohmann::json & target,nlohmann::json & source)62*6c038f26SEd Tanous void moveErrorsToErrorJson(nlohmann::json& target, nlohmann::json& source)
63*6c038f26SEd Tanous {
64*6c038f26SEd Tanous if (!source.is_object())
65*6c038f26SEd Tanous {
66*6c038f26SEd Tanous return;
67*6c038f26SEd Tanous }
68*6c038f26SEd Tanous auto errorIt = source.find("error");
69*6c038f26SEd Tanous if (errorIt == source.end())
70*6c038f26SEd Tanous {
71*6c038f26SEd Tanous // caller puts error message in root
72*6c038f26SEd Tanous messages::addMessageToErrorJson(target, source);
73*6c038f26SEd Tanous source.clear();
74*6c038f26SEd Tanous return;
75*6c038f26SEd Tanous }
76*6c038f26SEd Tanous auto extendedInfoIt = errorIt->find(messages::messageAnnotation);
77*6c038f26SEd Tanous if (extendedInfoIt == errorIt->end())
78*6c038f26SEd Tanous {
79*6c038f26SEd Tanous return;
80*6c038f26SEd Tanous }
81*6c038f26SEd Tanous const nlohmann::json::array_t* extendedInfo =
82*6c038f26SEd Tanous (*extendedInfoIt).get_ptr<const nlohmann::json::array_t*>();
83*6c038f26SEd Tanous if (extendedInfo == nullptr)
84*6c038f26SEd Tanous {
85*6c038f26SEd Tanous source.erase(errorIt);
86*6c038f26SEd Tanous return;
87*6c038f26SEd Tanous }
88*6c038f26SEd Tanous for (const nlohmann::json& message : *extendedInfo)
89*6c038f26SEd Tanous {
90*6c038f26SEd Tanous addMessageToErrorJson(target, message);
91*6c038f26SEd Tanous }
92*6c038f26SEd Tanous source.erase(errorIt);
93*6c038f26SEd Tanous }
94*6c038f26SEd Tanous
addMessageToJsonRoot(nlohmann::json & target,const nlohmann::json & message)95*6c038f26SEd Tanous void addMessageToJsonRoot(nlohmann::json& target, const nlohmann::json& message)
96*6c038f26SEd Tanous {
97*6c038f26SEd Tanous if (!target[messages::messageAnnotation].is_array())
98*6c038f26SEd Tanous {
99*6c038f26SEd Tanous // Force object to be an array
100*6c038f26SEd Tanous target[messages::messageAnnotation] = nlohmann::json::array();
101*6c038f26SEd Tanous }
102*6c038f26SEd Tanous
103*6c038f26SEd Tanous target[messages::messageAnnotation].push_back(message);
104*6c038f26SEd Tanous }
105*6c038f26SEd Tanous
addMessageToJson(nlohmann::json & target,const nlohmann::json & message,std::string_view fieldPath)106*6c038f26SEd Tanous void addMessageToJson(nlohmann::json& target, const nlohmann::json& message,
107*6c038f26SEd Tanous std::string_view fieldPath)
108*6c038f26SEd Tanous {
109*6c038f26SEd Tanous std::string extendedInfo(fieldPath);
110*6c038f26SEd Tanous extendedInfo += messages::messageAnnotation;
111*6c038f26SEd Tanous
112*6c038f26SEd Tanous nlohmann::json& field = target[extendedInfo];
113*6c038f26SEd Tanous if (!field.is_array())
114*6c038f26SEd Tanous {
115*6c038f26SEd Tanous // Force object to be an array
116*6c038f26SEd Tanous field = nlohmann::json::array();
117*6c038f26SEd Tanous }
118*6c038f26SEd Tanous
119*6c038f26SEd Tanous // Object exists and it is an array so we can just push in the message
120*6c038f26SEd Tanous field.push_back(message);
121*6c038f26SEd Tanous }
122*6c038f26SEd Tanous
123*6c038f26SEd Tanous } // namespace messages
124*6c038f26SEd Tanous } // namespace redfish
125