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 generated_exception::get_errno() const noexcept 20 { 21 return EIO; 22 } 23 24 SdBusError::SdBusError(int error_in, const char* prefix, 25 SdBusInterface* intf_in) : 26 SdBusError(error_in, std::string(prefix), intf_in) 27 {} 28 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 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 58 SdBusError::SdBusError(SdBusError&& other) : error(SD_BUS_ERROR_NULL) 59 { 60 move(std::move(other)); 61 } 62 63 SdBusError& SdBusError::operator=(SdBusError&& other) 64 { 65 if (this != &other) 66 { 67 move(std::move(other)); 68 } 69 return *this; 70 } 71 72 SdBusError::~SdBusError() 73 { 74 intf->sd_bus_error_free(&error); 75 } 76 77 const char* SdBusError::name() const noexcept 78 { 79 return error.name; 80 } 81 82 const char* SdBusError::description() const noexcept 83 { 84 return error.message; 85 } 86 87 const char* SdBusError::what() const noexcept 88 { 89 return full_message.c_str(); 90 } 91 92 int SdBusError::get_errno() const noexcept 93 { 94 return intf->sd_bus_error_get_errno(&this->error); 95 } 96 97 const sd_bus_error* SdBusError::get_error() const noexcept 98 { 99 return &error; 100 } 101 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 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 128 const char* InvalidEnumString::name() const noexcept 129 { 130 return errName; 131 } 132 133 const char* InvalidEnumString::description() const noexcept 134 { 135 return errDesc; 136 } 137 138 const char* InvalidEnumString::what() const noexcept 139 { 140 return errWhat; 141 } 142 143 int InvalidEnumString::get_errno() const noexcept 144 { 145 return EINVAL; 146 } 147 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 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 168 const char* UnpackPropertyError::name() const noexcept 169 { 170 return errName; 171 } 172 173 const char* UnpackPropertyError::description() const noexcept 174 { 175 return errDesc; 176 } 177 178 const char* UnpackPropertyError::what() const noexcept 179 { 180 return errWhatDetailed.c_str(); 181 } 182 183 int UnpackPropertyError::get_errno() const noexcept 184 { 185 return EINVAL; 186 } 187 188 const char* UnhandledStop::name() const noexcept 189 { 190 return errName; 191 } 192 193 const char* UnhandledStop::description() const noexcept 194 { 195 return errDesc; 196 } 197 198 const char* UnhandledStop::what() const noexcept 199 { 200 return errWhat; 201 } 202 203 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