17f664254SPatrick Williams #include <sdbusplus/exception.hpp>
2*b08d14ddSPatrick Williams #include <sdbusplus/sdbuspp_support/event.hpp>
37f664254SPatrick Williams
4b6f729d6SPatrick Williams #include <cerrno>
57f664254SPatrick Williams #include <stdexcept>
67f664254SPatrick Williams #include <utility>
77f664254SPatrick Williams
80c8136a4SPatrick Williams #ifdef __clang__
90c8136a4SPatrick Williams #pragma clang diagnostic push
100c8136a4SPatrick Williams #pragma clang diagnostic ignored "-Wc99-extensions"
110c8136a4SPatrick Williams #endif
120c8136a4SPatrick Williams
13*b08d14ddSPatrick Williams namespace sdbusplus::exception
147f664254SPatrick Williams {
157f664254SPatrick Williams
unused() const16f289c65fSPatrick Williams void exception::unused() const noexcept {}
17a8e3502cSPatrick Williams
set_error(sd_bus_error * e) const18a4bfefdeSPatrick Williams int exception::set_error(sd_bus_error* e) const
19a4bfefdeSPatrick Williams {
20a4bfefdeSPatrick Williams return sd_bus_error_set(e, name(), description());
21a4bfefdeSPatrick Williams }
22a4bfefdeSPatrick Williams
set_error(SdBusInterface * i,sd_bus_error * e) const23a4bfefdeSPatrick Williams int exception::set_error(SdBusInterface* i, sd_bus_error* e) const
24a4bfefdeSPatrick Williams {
25a4bfefdeSPatrick Williams return i->sd_bus_error_set(e, name(), description());
26a4bfefdeSPatrick Williams }
27a4bfefdeSPatrick Williams
get_errno() const2815228663SPatrick Williams int generated_exception::get_errno() const noexcept
2915228663SPatrick Williams {
3015228663SPatrick Williams return EIO;
3115228663SPatrick Williams }
3215228663SPatrick Williams
SdBusError(int error_in,const char * prefix,SdBusInterface * intf_in)33ed4a5a64SEd Tanous SdBusError::SdBusError(int error_in, const char* prefix,
34ed4a5a64SEd Tanous SdBusInterface* intf_in) :
3570bcf14cSPatrick Williams SdBusError(error_in, std::string(prefix), intf_in)
3670bcf14cSPatrick Williams {}
3770bcf14cSPatrick Williams
SdBusError(int error_in,std::string && prefix,SdBusInterface * intf_in)3870bcf14cSPatrick Williams SdBusError::SdBusError(int error_in, std::string&& prefix,
3970bcf14cSPatrick Williams SdBusInterface* intf_in) :
4006f265f6SPatrick Williams error(SD_BUS_ERROR_NULL), intf(intf_in)
417f664254SPatrick Williams {
427f664254SPatrick Williams // We can't check the output of intf->sd_bus_error_set_errno() because
437f664254SPatrick Williams // it returns the input errorcode. We don't want to try and guess
447f664254SPatrick Williams // possible error statuses. Instead, check to see if the error was
457f664254SPatrick Williams // constructed to determine success.
46ed4a5a64SEd Tanous intf->sd_bus_error_set_errno(&this->error, error_in);
477f664254SPatrick Williams if (!intf->sd_bus_error_is_set(&this->error))
487f664254SPatrick Williams {
497f664254SPatrick Williams throw std::runtime_error("Failed to create SdBusError");
507f664254SPatrick Williams }
517f664254SPatrick Williams
5270bcf14cSPatrick Williams populateMessage(std::move(prefix));
537f664254SPatrick Williams }
547f664254SPatrick Williams
SdBusError(sd_bus_error * error_in,const char * prefix,SdBusInterface * intf_in)55ed4a5a64SEd Tanous SdBusError::SdBusError(sd_bus_error* error_in, const char* prefix,
56ed4a5a64SEd Tanous SdBusInterface* intf_in) :
5706f265f6SPatrick Williams error(*error_in), intf(intf_in)
587f664254SPatrick Williams {
597f664254SPatrick Williams // We own the error so remove the caller's reference
60ed4a5a64SEd Tanous *error_in = SD_BUS_ERROR_NULL;
617f664254SPatrick Williams
6270bcf14cSPatrick Williams populateMessage(std::string(prefix));
637f664254SPatrick Williams }
647f664254SPatrick Williams
SdBusError(SdBusError && other)657f664254SPatrick Williams SdBusError::SdBusError(SdBusError&& other) : error(SD_BUS_ERROR_NULL)
667f664254SPatrick Williams {
677f664254SPatrick Williams move(std::move(other));
687f664254SPatrick Williams }
697f664254SPatrick Williams
operator =(SdBusError && other)707f664254SPatrick Williams SdBusError& SdBusError::operator=(SdBusError&& other)
717f664254SPatrick Williams {
727f664254SPatrick Williams if (this != &other)
737f664254SPatrick Williams {
747f664254SPatrick Williams move(std::move(other));
757f664254SPatrick Williams }
767f664254SPatrick Williams return *this;
777f664254SPatrick Williams }
787f664254SPatrick Williams
~SdBusError()797f664254SPatrick Williams SdBusError::~SdBusError()
807f664254SPatrick Williams {
817f664254SPatrick Williams intf->sd_bus_error_free(&error);
827f664254SPatrick Williams }
837f664254SPatrick Williams
name() const847f664254SPatrick Williams const char* SdBusError::name() const noexcept
857f664254SPatrick Williams {
867f664254SPatrick Williams return error.name;
877f664254SPatrick Williams }
887f664254SPatrick Williams
description() const897f664254SPatrick Williams const char* SdBusError::description() const noexcept
907f664254SPatrick Williams {
917f664254SPatrick Williams return error.message;
927f664254SPatrick Williams }
937f664254SPatrick Williams
what() const947f664254SPatrick Williams const char* SdBusError::what() const noexcept
957f664254SPatrick Williams {
967f664254SPatrick Williams return full_message.c_str();
977f664254SPatrick Williams }
987f664254SPatrick Williams
get_errno() const997f664254SPatrick Williams int SdBusError::get_errno() const noexcept
1007f664254SPatrick Williams {
1017f664254SPatrick Williams return intf->sd_bus_error_get_errno(&this->error);
1027f664254SPatrick Williams }
1037f664254SPatrick Williams
get_error() const1047f664254SPatrick Williams const sd_bus_error* SdBusError::get_error() const noexcept
1057f664254SPatrick Williams {
1067f664254SPatrick Williams return &error;
1077f664254SPatrick Williams }
1087f664254SPatrick Williams
populateMessage(std::string && prefix)10970bcf14cSPatrick Williams void SdBusError::populateMessage(std::string&& prefix)
1107f664254SPatrick Williams {
11170bcf14cSPatrick Williams full_message = std::move(prefix);
1127f664254SPatrick Williams if (error.name)
1137f664254SPatrick Williams {
1147f664254SPatrick Williams full_message += ": ";
1157f664254SPatrick Williams full_message += error.name;
1167f664254SPatrick Williams }
1177f664254SPatrick Williams if (error.message)
1187f664254SPatrick Williams {
1197f664254SPatrick Williams full_message += ": ";
1207f664254SPatrick Williams full_message += error.message;
1217f664254SPatrick Williams }
1227f664254SPatrick Williams }
1237f664254SPatrick Williams
move(SdBusError && other)1247f664254SPatrick Williams void SdBusError::move(SdBusError&& other)
1257f664254SPatrick Williams {
1267f664254SPatrick Williams intf = std::move(other.intf);
1277f664254SPatrick Williams
1287f664254SPatrick Williams intf->sd_bus_error_free(&error);
1297f664254SPatrick Williams error = other.error;
1307f664254SPatrick Williams other.error = SD_BUS_ERROR_NULL;
1317f664254SPatrick Williams
1327f664254SPatrick Williams full_message = std::move(other.full_message);
1337f664254SPatrick Williams }
1347f664254SPatrick Williams
name() const1357f664254SPatrick Williams const char* InvalidEnumString::name() const noexcept
1367f664254SPatrick Williams {
1377f664254SPatrick Williams return errName;
1387f664254SPatrick Williams }
1397f664254SPatrick Williams
description() const1407f664254SPatrick Williams const char* InvalidEnumString::description() const noexcept
1417f664254SPatrick Williams {
1427f664254SPatrick Williams return errDesc;
1437f664254SPatrick Williams }
1447f664254SPatrick Williams
what() const1457f664254SPatrick Williams const char* InvalidEnumString::what() const noexcept
1467f664254SPatrick Williams {
1477f664254SPatrick Williams return errWhat;
1487f664254SPatrick Williams }
1497f664254SPatrick Williams
get_errno() const150bd372ecbSPatrick Williams int InvalidEnumString::get_errno() const noexcept
151bd372ecbSPatrick Williams {
152bd372ecbSPatrick Williams return EINVAL;
153bd372ecbSPatrick Williams }
154bd372ecbSPatrick Williams
unpackErrorReasonToString(const UnpackErrorReason reason)155c3484735SEd Tanous static std::string unpackErrorReasonToString(const UnpackErrorReason reason)
156c8447d52SKrzysztof Grobelny {
157c8447d52SKrzysztof Grobelny switch (reason)
158c8447d52SKrzysztof Grobelny {
159c8447d52SKrzysztof Grobelny case UnpackErrorReason::missingProperty:
160c8447d52SKrzysztof Grobelny return "Missing property";
161c8447d52SKrzysztof Grobelny case UnpackErrorReason::wrongType:
162c8447d52SKrzysztof Grobelny return "Type not matched";
163c8447d52SKrzysztof Grobelny }
164c8447d52SKrzysztof Grobelny return "Unknown";
165c8447d52SKrzysztof Grobelny }
166c8447d52SKrzysztof Grobelny
UnpackPropertyError(std::string_view propertyNameIn,const UnpackErrorReason reasonIn)1676d83cf53SSzymon Dompke UnpackPropertyError::UnpackPropertyError(std::string_view propertyNameIn,
168c8447d52SKrzysztof Grobelny const UnpackErrorReason reasonIn) :
16906f265f6SPatrick Williams propertyName(propertyNameIn), reason(reasonIn),
1706d83cf53SSzymon Dompke errWhatDetailed(std::string(errWhat) + " PropertyName: '" + propertyName +
171c8447d52SKrzysztof Grobelny "', Reason: '" + unpackErrorReasonToString(reason) + "'.")
17209b88f26SKrzysztof Grobelny {}
17309b88f26SKrzysztof Grobelny
name() const17409b88f26SKrzysztof Grobelny const char* UnpackPropertyError::name() const noexcept
17509b88f26SKrzysztof Grobelny {
17609b88f26SKrzysztof Grobelny return errName;
17709b88f26SKrzysztof Grobelny }
17809b88f26SKrzysztof Grobelny
description() const17909b88f26SKrzysztof Grobelny const char* UnpackPropertyError::description() const noexcept
18009b88f26SKrzysztof Grobelny {
18109b88f26SKrzysztof Grobelny return errDesc;
18209b88f26SKrzysztof Grobelny }
18309b88f26SKrzysztof Grobelny
what() const18409b88f26SKrzysztof Grobelny const char* UnpackPropertyError::what() const noexcept
18509b88f26SKrzysztof Grobelny {
1866d83cf53SSzymon Dompke return errWhatDetailed.c_str();
18709b88f26SKrzysztof Grobelny }
18809b88f26SKrzysztof Grobelny
get_errno() const189bd372ecbSPatrick Williams int UnpackPropertyError::get_errno() const noexcept
190bd372ecbSPatrick Williams {
191bd372ecbSPatrick Williams return EINVAL;
192bd372ecbSPatrick Williams }
193bd372ecbSPatrick Williams
name() const1944cfc284dSPatrick Williams const char* UnhandledStop::name() const noexcept
1954cfc284dSPatrick Williams {
1964cfc284dSPatrick Williams return errName;
1974cfc284dSPatrick Williams }
1984cfc284dSPatrick Williams
description() const1994cfc284dSPatrick Williams const char* UnhandledStop::description() const noexcept
2004cfc284dSPatrick Williams {
2014cfc284dSPatrick Williams return errDesc;
2024cfc284dSPatrick Williams }
2034cfc284dSPatrick Williams
what() const2044cfc284dSPatrick Williams const char* UnhandledStop::what() const noexcept
2054cfc284dSPatrick Williams {
2064cfc284dSPatrick Williams return errWhat;
2074cfc284dSPatrick Williams }
2084cfc284dSPatrick Williams
get_errno() const2094cfc284dSPatrick Williams int UnhandledStop::get_errno() const noexcept
2104cfc284dSPatrick Williams {
2114cfc284dSPatrick Williams return ECANCELED;
2124cfc284dSPatrick Williams }
2134cfc284dSPatrick Williams
214*b08d14ddSPatrick Williams static std::unordered_map<std::string, sdbusplus::sdbuspp::register_hook>
215*b08d14ddSPatrick Williams event_hooks = {};
216*b08d14ddSPatrick Williams
throw_via_json(const nlohmann::json & j,const std::source_location & source)217*b08d14ddSPatrick Williams void throw_via_json(const nlohmann::json& j, const std::source_location& source)
218*b08d14ddSPatrick Williams {
219*b08d14ddSPatrick Williams for (const auto& i : j.items())
220*b08d14ddSPatrick Williams {
221*b08d14ddSPatrick Williams if (auto it = event_hooks.find(i.key()); it != event_hooks.end())
222*b08d14ddSPatrick Williams {
223*b08d14ddSPatrick Williams it->second(j, source);
224*b08d14ddSPatrick Williams }
225*b08d14ddSPatrick Williams }
226*b08d14ddSPatrick Williams }
227*b08d14ddSPatrick Williams
known_events()228*b08d14ddSPatrick Williams auto known_events() -> std::vector<std::string>
229*b08d14ddSPatrick Williams {
230*b08d14ddSPatrick Williams std::vector<std::string> result{};
231*b08d14ddSPatrick Williams
232*b08d14ddSPatrick Williams for (const auto& [key, _] : event_hooks)
233*b08d14ddSPatrick Williams {
234*b08d14ddSPatrick Williams result.emplace_back(key);
235*b08d14ddSPatrick Williams }
236*b08d14ddSPatrick Williams
237*b08d14ddSPatrick Williams std::ranges::sort(result);
238*b08d14ddSPatrick Williams
239*b08d14ddSPatrick Williams return result;
240*b08d14ddSPatrick Williams }
241*b08d14ddSPatrick Williams
242*b08d14ddSPatrick Williams } // namespace sdbusplus::exception
243*b08d14ddSPatrick Williams
244*b08d14ddSPatrick Williams namespace sdbusplus::sdbuspp
245*b08d14ddSPatrick Williams {
246*b08d14ddSPatrick Williams
register_event(const std::string & event,register_hook throw_hook)247*b08d14ddSPatrick Williams void register_event(const std::string& event, register_hook throw_hook)
248*b08d14ddSPatrick Williams {
249*b08d14ddSPatrick Williams sdbusplus::exception::event_hooks.emplace(event, throw_hook);
250*b08d14ddSPatrick Williams }
251*b08d14ddSPatrick Williams
252*b08d14ddSPatrick Williams } // namespace sdbusplus::sdbuspp
2530c8136a4SPatrick Williams
2540c8136a4SPatrick Williams #ifdef __clang__
2550c8136a4SPatrick Williams #pragma clang diagnostic pop
2560c8136a4SPatrick Williams #endif
257