xref: /openbmc/sdbusplus/src/exception.cpp (revision 36071788)
1 #include <sdbusplus/exception.hpp>
2 
3 #include <cerrno>
4 #include <stdexcept>
5 #include <utility>
6 
7 #ifdef __clang__
8 #pragma clang diagnostic push
9 #pragma clang diagnostic ignored "-Wc99-extensions"
10 #endif
11 
12 namespace sdbusplus
13 {
14 namespace exception
15 {
16 
17 void exception::unused() const noexcept
18 {}
19 
20 int generated_exception::get_errno() const noexcept
21 {
22     return EIO;
23 }
24 
25 SdBusError::SdBusError(int error, const char* prefix, SdBusInterface* intf) :
26     error(SD_BUS_ERROR_NULL), intf(intf)
27 {
28     // We can't check the output of intf->sd_bus_error_set_errno() because
29     // it returns the input errorcode. We don't want to try and guess
30     // possible error statuses. Instead, check to see if the error was
31     // constructed to determine success.
32     intf->sd_bus_error_set_errno(&this->error, error);
33     if (!intf->sd_bus_error_is_set(&this->error))
34     {
35         throw std::runtime_error("Failed to create SdBusError");
36     }
37 
38     populateMessage(prefix);
39 }
40 
41 SdBusError::SdBusError(sd_bus_error* error, const char* prefix,
42                        SdBusInterface* intf) :
43     error(*error),
44     intf(intf)
45 {
46     // We own the error so remove the caller's reference
47     *error = SD_BUS_ERROR_NULL;
48 
49     populateMessage(prefix);
50 }
51 
52 SdBusError::SdBusError(SdBusError&& other) : error(SD_BUS_ERROR_NULL)
53 {
54     move(std::move(other));
55 }
56 
57 SdBusError& SdBusError::operator=(SdBusError&& other)
58 {
59     if (this != &other)
60     {
61         move(std::move(other));
62     }
63     return *this;
64 }
65 
66 SdBusError::~SdBusError()
67 {
68     intf->sd_bus_error_free(&error);
69 }
70 
71 const char* SdBusError::name() const noexcept
72 {
73     return error.name;
74 }
75 
76 const char* SdBusError::description() const noexcept
77 {
78     return error.message;
79 }
80 
81 const char* SdBusError::what() const noexcept
82 {
83     return full_message.c_str();
84 }
85 
86 int SdBusError::get_errno() const noexcept
87 {
88     return intf->sd_bus_error_get_errno(&this->error);
89 }
90 
91 const sd_bus_error* SdBusError::get_error() const noexcept
92 {
93     return &error;
94 }
95 
96 void SdBusError::populateMessage(const char* prefix)
97 {
98     full_message = prefix;
99     if (error.name)
100     {
101         full_message += ": ";
102         full_message += error.name;
103     }
104     if (error.message)
105     {
106         full_message += ": ";
107         full_message += error.message;
108     }
109 }
110 
111 void SdBusError::move(SdBusError&& other)
112 {
113     intf = std::move(other.intf);
114 
115     intf->sd_bus_error_free(&error);
116     error = other.error;
117     other.error = SD_BUS_ERROR_NULL;
118 
119     full_message = std::move(other.full_message);
120 }
121 
122 const char* InvalidEnumString::name() const noexcept
123 {
124     return errName;
125 }
126 
127 const char* InvalidEnumString::description() const noexcept
128 {
129     return errDesc;
130 }
131 
132 const char* InvalidEnumString::what() const noexcept
133 {
134     return errWhat;
135 }
136 
137 int InvalidEnumString::get_errno() const noexcept
138 {
139     return EINVAL;
140 }
141 
142 std::string unpackErrorReasonToString(const UnpackErrorReason reason)
143 {
144     switch (reason)
145     {
146         case UnpackErrorReason::missingProperty:
147             return "Missing property";
148         case UnpackErrorReason::wrongType:
149             return "Type not matched";
150     }
151     return "Unknown";
152 }
153 
154 UnpackPropertyError::UnpackPropertyError(std::string_view propertyNameIn,
155                                          const UnpackErrorReason reasonIn) :
156     propertyName(propertyNameIn),
157     reason(reasonIn),
158     errWhatDetailed(std::string(errWhat) + " PropertyName: '" + propertyName +
159                     "', Reason: '" + unpackErrorReasonToString(reason) + "'.")
160 {}
161 
162 const char* UnpackPropertyError::name() const noexcept
163 {
164     return errName;
165 }
166 
167 const char* UnpackPropertyError::description() const noexcept
168 {
169     return errDesc;
170 }
171 
172 const char* UnpackPropertyError::what() const noexcept
173 {
174     return errWhatDetailed.c_str();
175 }
176 
177 int UnpackPropertyError::get_errno() const noexcept
178 {
179     return EINVAL;
180 }
181 
182 } // namespace exception
183 } // namespace sdbusplus
184 
185 #ifdef __clang__
186 #pragma clang diagnostic pop
187 #endif
188