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