17f664254SPatrick Williams #include <sdbusplus/exception.hpp> 27f664254SPatrick Williams 3b6f729d6SPatrick Williams #include <cerrno> 47f664254SPatrick Williams #include <stdexcept> 57f664254SPatrick Williams #include <utility> 67f664254SPatrick Williams 70c8136a4SPatrick Williams #ifdef __clang__ 80c8136a4SPatrick Williams #pragma clang diagnostic push 90c8136a4SPatrick Williams #pragma clang diagnostic ignored "-Wc99-extensions" 100c8136a4SPatrick Williams #endif 110c8136a4SPatrick Williams 127f664254SPatrick Williams namespace sdbusplus 137f664254SPatrick Williams { 147f664254SPatrick Williams namespace exception 157f664254SPatrick Williams { 167f664254SPatrick Williams 17f289c65fSPatrick Williams void exception::unused() const noexcept {} 18a8e3502cSPatrick Williams 1915228663SPatrick Williams int generated_exception::get_errno() const noexcept 2015228663SPatrick Williams { 2115228663SPatrick Williams return EIO; 2215228663SPatrick Williams } 2315228663SPatrick Williams 24*ed4a5a64SEd Tanous SdBusError::SdBusError(int error_in, const char* prefix, 25*ed4a5a64SEd Tanous SdBusInterface* intf_in) : 26*ed4a5a64SEd Tanous error(SD_BUS_ERROR_NULL), 27*ed4a5a64SEd Tanous intf(intf_in) 287f664254SPatrick Williams { 297f664254SPatrick Williams // We can't check the output of intf->sd_bus_error_set_errno() because 307f664254SPatrick Williams // it returns the input errorcode. We don't want to try and guess 317f664254SPatrick Williams // possible error statuses. Instead, check to see if the error was 327f664254SPatrick Williams // constructed to determine success. 33*ed4a5a64SEd Tanous intf->sd_bus_error_set_errno(&this->error, error_in); 347f664254SPatrick Williams if (!intf->sd_bus_error_is_set(&this->error)) 357f664254SPatrick Williams { 367f664254SPatrick Williams throw std::runtime_error("Failed to create SdBusError"); 377f664254SPatrick Williams } 387f664254SPatrick Williams 397f664254SPatrick Williams populateMessage(prefix); 407f664254SPatrick Williams } 417f664254SPatrick Williams 42*ed4a5a64SEd Tanous SdBusError::SdBusError(sd_bus_error* error_in, const char* prefix, 43*ed4a5a64SEd Tanous SdBusInterface* intf_in) : 44*ed4a5a64SEd Tanous error(*error_in), 45*ed4a5a64SEd Tanous intf(intf_in) 467f664254SPatrick Williams { 477f664254SPatrick Williams // We own the error so remove the caller's reference 48*ed4a5a64SEd Tanous *error_in = SD_BUS_ERROR_NULL; 497f664254SPatrick Williams 507f664254SPatrick Williams populateMessage(prefix); 517f664254SPatrick Williams } 527f664254SPatrick Williams 537f664254SPatrick Williams SdBusError::SdBusError(SdBusError&& other) : error(SD_BUS_ERROR_NULL) 547f664254SPatrick Williams { 557f664254SPatrick Williams move(std::move(other)); 567f664254SPatrick Williams } 577f664254SPatrick Williams 587f664254SPatrick Williams SdBusError& SdBusError::operator=(SdBusError&& other) 597f664254SPatrick Williams { 607f664254SPatrick Williams if (this != &other) 617f664254SPatrick Williams { 627f664254SPatrick Williams move(std::move(other)); 637f664254SPatrick Williams } 647f664254SPatrick Williams return *this; 657f664254SPatrick Williams } 667f664254SPatrick Williams 677f664254SPatrick Williams SdBusError::~SdBusError() 687f664254SPatrick Williams { 697f664254SPatrick Williams intf->sd_bus_error_free(&error); 707f664254SPatrick Williams } 717f664254SPatrick Williams 727f664254SPatrick Williams const char* SdBusError::name() const noexcept 737f664254SPatrick Williams { 747f664254SPatrick Williams return error.name; 757f664254SPatrick Williams } 767f664254SPatrick Williams 777f664254SPatrick Williams const char* SdBusError::description() const noexcept 787f664254SPatrick Williams { 797f664254SPatrick Williams return error.message; 807f664254SPatrick Williams } 817f664254SPatrick Williams 827f664254SPatrick Williams const char* SdBusError::what() const noexcept 837f664254SPatrick Williams { 847f664254SPatrick Williams return full_message.c_str(); 857f664254SPatrick Williams } 867f664254SPatrick Williams 877f664254SPatrick Williams int SdBusError::get_errno() const noexcept 887f664254SPatrick Williams { 897f664254SPatrick Williams return intf->sd_bus_error_get_errno(&this->error); 907f664254SPatrick Williams } 917f664254SPatrick Williams 927f664254SPatrick Williams const sd_bus_error* SdBusError::get_error() const noexcept 937f664254SPatrick Williams { 947f664254SPatrick Williams return &error; 957f664254SPatrick Williams } 967f664254SPatrick Williams 977f664254SPatrick Williams void SdBusError::populateMessage(const char* prefix) 987f664254SPatrick Williams { 997f664254SPatrick Williams full_message = prefix; 1007f664254SPatrick Williams if (error.name) 1017f664254SPatrick Williams { 1027f664254SPatrick Williams full_message += ": "; 1037f664254SPatrick Williams full_message += error.name; 1047f664254SPatrick Williams } 1057f664254SPatrick Williams if (error.message) 1067f664254SPatrick Williams { 1077f664254SPatrick Williams full_message += ": "; 1087f664254SPatrick Williams full_message += error.message; 1097f664254SPatrick Williams } 1107f664254SPatrick Williams } 1117f664254SPatrick Williams 1127f664254SPatrick Williams void SdBusError::move(SdBusError&& other) 1137f664254SPatrick Williams { 1147f664254SPatrick Williams intf = std::move(other.intf); 1157f664254SPatrick Williams 1167f664254SPatrick Williams intf->sd_bus_error_free(&error); 1177f664254SPatrick Williams error = other.error; 1187f664254SPatrick Williams other.error = SD_BUS_ERROR_NULL; 1197f664254SPatrick Williams 1207f664254SPatrick Williams full_message = std::move(other.full_message); 1217f664254SPatrick Williams } 1227f664254SPatrick Williams 1237f664254SPatrick Williams const char* InvalidEnumString::name() const noexcept 1247f664254SPatrick Williams { 1257f664254SPatrick Williams return errName; 1267f664254SPatrick Williams } 1277f664254SPatrick Williams 1287f664254SPatrick Williams const char* InvalidEnumString::description() const noexcept 1297f664254SPatrick Williams { 1307f664254SPatrick Williams return errDesc; 1317f664254SPatrick Williams } 1327f664254SPatrick Williams 1337f664254SPatrick Williams const char* InvalidEnumString::what() const noexcept 1347f664254SPatrick Williams { 1357f664254SPatrick Williams return errWhat; 1367f664254SPatrick Williams } 1377f664254SPatrick Williams 138bd372ecbSPatrick Williams int InvalidEnumString::get_errno() const noexcept 139bd372ecbSPatrick Williams { 140bd372ecbSPatrick Williams return EINVAL; 141bd372ecbSPatrick Williams } 142bd372ecbSPatrick Williams 143c3484735SEd Tanous static std::string unpackErrorReasonToString(const UnpackErrorReason reason) 144c8447d52SKrzysztof Grobelny { 145c8447d52SKrzysztof Grobelny switch (reason) 146c8447d52SKrzysztof Grobelny { 147c8447d52SKrzysztof Grobelny case UnpackErrorReason::missingProperty: 148c8447d52SKrzysztof Grobelny return "Missing property"; 149c8447d52SKrzysztof Grobelny case UnpackErrorReason::wrongType: 150c8447d52SKrzysztof Grobelny return "Type not matched"; 151c8447d52SKrzysztof Grobelny } 152c8447d52SKrzysztof Grobelny return "Unknown"; 153c8447d52SKrzysztof Grobelny } 154c8447d52SKrzysztof Grobelny 1556d83cf53SSzymon Dompke UnpackPropertyError::UnpackPropertyError(std::string_view propertyNameIn, 156c8447d52SKrzysztof Grobelny const UnpackErrorReason reasonIn) : 1576d83cf53SSzymon Dompke propertyName(propertyNameIn), 1586d83cf53SSzymon Dompke reason(reasonIn), 1596d83cf53SSzymon Dompke errWhatDetailed(std::string(errWhat) + " PropertyName: '" + propertyName + 160c8447d52SKrzysztof Grobelny "', Reason: '" + unpackErrorReasonToString(reason) + "'.") 16109b88f26SKrzysztof Grobelny {} 16209b88f26SKrzysztof Grobelny 16309b88f26SKrzysztof Grobelny const char* UnpackPropertyError::name() const noexcept 16409b88f26SKrzysztof Grobelny { 16509b88f26SKrzysztof Grobelny return errName; 16609b88f26SKrzysztof Grobelny } 16709b88f26SKrzysztof Grobelny 16809b88f26SKrzysztof Grobelny const char* UnpackPropertyError::description() const noexcept 16909b88f26SKrzysztof Grobelny { 17009b88f26SKrzysztof Grobelny return errDesc; 17109b88f26SKrzysztof Grobelny } 17209b88f26SKrzysztof Grobelny 17309b88f26SKrzysztof Grobelny const char* UnpackPropertyError::what() const noexcept 17409b88f26SKrzysztof Grobelny { 1756d83cf53SSzymon Dompke return errWhatDetailed.c_str(); 17609b88f26SKrzysztof Grobelny } 17709b88f26SKrzysztof Grobelny 178bd372ecbSPatrick Williams int UnpackPropertyError::get_errno() const noexcept 179bd372ecbSPatrick Williams { 180bd372ecbSPatrick Williams return EINVAL; 181bd372ecbSPatrick Williams } 182bd372ecbSPatrick Williams 1834cfc284dSPatrick Williams const char* UnhandledStop::name() const noexcept 1844cfc284dSPatrick Williams { 1854cfc284dSPatrick Williams return errName; 1864cfc284dSPatrick Williams } 1874cfc284dSPatrick Williams 1884cfc284dSPatrick Williams const char* UnhandledStop::description() const noexcept 1894cfc284dSPatrick Williams { 1904cfc284dSPatrick Williams return errDesc; 1914cfc284dSPatrick Williams } 1924cfc284dSPatrick Williams 1934cfc284dSPatrick Williams const char* UnhandledStop::what() const noexcept 1944cfc284dSPatrick Williams { 1954cfc284dSPatrick Williams return errWhat; 1964cfc284dSPatrick Williams } 1974cfc284dSPatrick Williams 1984cfc284dSPatrick Williams int UnhandledStop::get_errno() const noexcept 1994cfc284dSPatrick Williams { 2004cfc284dSPatrick Williams return ECANCELED; 2014cfc284dSPatrick Williams } 2024cfc284dSPatrick Williams 2037f664254SPatrick Williams } // namespace exception 2047f664254SPatrick Williams } // namespace sdbusplus 2050c8136a4SPatrick Williams 2060c8136a4SPatrick Williams #ifdef __clang__ 2070c8136a4SPatrick Williams #pragma clang diagnostic pop 2080c8136a4SPatrick Williams #endif 209