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