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