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