1 #include <sdbusplus/exception.hpp> 2 3 #include <stdexcept> 4 #include <utility> 5 6 #ifdef __clang__ 7 #pragma clang diagnostic push 8 #pragma clang diagnostic ignored "-Wc99-extensions" 9 #endif 10 11 namespace sdbusplus 12 { 13 namespace exception 14 { 15 16 SdBusError::SdBusError(int error, const char* prefix, SdBusInterface* intf) : 17 error(SD_BUS_ERROR_NULL), intf(intf) 18 { 19 // We can't check the output of intf->sd_bus_error_set_errno() because 20 // it returns the input errorcode. We don't want to try and guess 21 // possible error statuses. Instead, check to see if the error was 22 // constructed to determine success. 23 intf->sd_bus_error_set_errno(&this->error, error); 24 if (!intf->sd_bus_error_is_set(&this->error)) 25 { 26 throw std::runtime_error("Failed to create SdBusError"); 27 } 28 29 populateMessage(prefix); 30 } 31 32 SdBusError::SdBusError(sd_bus_error* error, const char* prefix, 33 SdBusInterface* intf) : 34 error(*error), 35 intf(intf) 36 { 37 // We own the error so remove the caller's reference 38 *error = SD_BUS_ERROR_NULL; 39 40 populateMessage(prefix); 41 } 42 43 SdBusError::SdBusError(SdBusError&& other) : error(SD_BUS_ERROR_NULL) 44 { 45 move(std::move(other)); 46 } 47 48 SdBusError& SdBusError::operator=(SdBusError&& other) 49 { 50 if (this != &other) 51 { 52 move(std::move(other)); 53 } 54 return *this; 55 } 56 57 SdBusError::~SdBusError() 58 { 59 intf->sd_bus_error_free(&error); 60 } 61 62 const char* SdBusError::name() const noexcept 63 { 64 return error.name; 65 } 66 67 const char* SdBusError::description() const noexcept 68 { 69 return error.message; 70 } 71 72 const char* SdBusError::what() const noexcept 73 { 74 return full_message.c_str(); 75 } 76 77 int SdBusError::get_errno() const noexcept 78 { 79 return intf->sd_bus_error_get_errno(&this->error); 80 } 81 82 const sd_bus_error* SdBusError::get_error() const noexcept 83 { 84 return &error; 85 } 86 87 void SdBusError::populateMessage(const char* prefix) 88 { 89 full_message = prefix; 90 if (error.name) 91 { 92 full_message += ": "; 93 full_message += error.name; 94 } 95 if (error.message) 96 { 97 full_message += ": "; 98 full_message += error.message; 99 } 100 } 101 102 void SdBusError::move(SdBusError&& other) 103 { 104 intf = std::move(other.intf); 105 106 intf->sd_bus_error_free(&error); 107 error = other.error; 108 other.error = SD_BUS_ERROR_NULL; 109 110 full_message = std::move(other.full_message); 111 } 112 113 const char* InvalidEnumString::name() const noexcept 114 { 115 return errName; 116 } 117 118 const char* InvalidEnumString::description() const noexcept 119 { 120 return errDesc; 121 } 122 123 const char* InvalidEnumString::what() const noexcept 124 { 125 return errWhat; 126 } 127 128 UnpackPropertyError::UnpackPropertyError(std::string_view propertyName, 129 std::string_view reason) : 130 propertyName(propertyName), 131 reason(reason) 132 {} 133 134 const char* UnpackPropertyError::name() const noexcept 135 { 136 return errName; 137 } 138 139 const char* UnpackPropertyError::description() const noexcept 140 { 141 return errDesc; 142 } 143 144 const char* UnpackPropertyError::what() const noexcept 145 { 146 return errWhat; 147 } 148 149 } // namespace exception 150 } // namespace sdbusplus 151 152 #ifdef __clang__ 153 #pragma clang diagnostic pop 154 #endif 155