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