1 #pragma once 2 3 #include <systemd/sd-bus.h> 4 5 #include <sdbusplus/sdbus.hpp> 6 7 #include <exception> 8 #include <string> 9 10 namespace sdbusplus 11 { 12 13 enum class UnpackErrorReason 14 { 15 missingProperty, 16 wrongType 17 }; 18 19 namespace exception 20 { 21 22 /** Base exception class for all sdbusplus exceptions, including those created 23 * by the bindings. */ 24 struct exception : public std::exception 25 { 26 virtual const char* name() const noexcept = 0; 27 virtual const char* description() const noexcept = 0; 28 virtual int get_errno() const noexcept = 0; 29 30 private: 31 // This unused function is to ensure that the vtable for this class is 32 // properly emitted when `-flto=auto` is used, which is the default in 33 // Yocto builds. Without this, the vtable is a hidden symbol and no 34 // users can inherit from our exception type directly. 35 virtual void unused() const noexcept; 36 }; 37 38 /** base exception class for all errors created by the sdbus++ generator */ 39 struct generated_exception : public exception 40 { 41 int get_errno() const noexcept override; 42 }; 43 44 /** base exception class for all errors generated by sdbusplus itself. */ 45 struct internal_exception : public exception 46 {}; 47 48 /** Exception for when an underlying sd_bus method call fails. */ 49 class SdBusError final : public internal_exception 50 { 51 public: 52 /** Errno must be positive */ 53 SdBusError(int error, const char* prefix, 54 SdBusInterface* intf = &sdbus_impl); 55 SdBusError(int error, std::string&& prefix, 56 SdBusInterface* intf = &sdbus_impl); 57 /** Becomes the owner of the error */ 58 SdBusError(sd_bus_error* error, const char* prefix, 59 SdBusInterface* intf = &sdbus_impl); 60 61 SdBusError(const SdBusError&) = delete; 62 SdBusError& operator=(const SdBusError&) = delete; 63 SdBusError(SdBusError&& other); 64 SdBusError& operator=(SdBusError&& other); 65 ~SdBusError() override; 66 67 const char* name() const noexcept override; 68 const char* description() const noexcept override; 69 const char* what() const noexcept override; 70 int get_errno() const noexcept override; 71 const sd_bus_error* get_error() const noexcept; 72 73 private: 74 sd_bus_error error; 75 std::string full_message; 76 SdBusInterface* intf; 77 78 /** Populates the full_message from the stored 79 * error and the passed in prefix. */ 80 void populateMessage(std::string&& prefix); 81 82 /** Helper to reduce duplicate move logic */ 83 void move(SdBusError&& other); 84 }; 85 86 /** Exception for when an invalid conversion from string to enum is 87 * attempted. */ 88 struct InvalidEnumString final : public internal_exception 89 { 90 static constexpr auto errName = 91 "xyz.openbmc_project.sdbusplus.Error.InvalidEnumString"; 92 static constexpr auto errDesc = 93 "An enumeration mapping was attempted for which no valid enumeration " 94 "value exists."; 95 static constexpr auto errWhat = 96 "xyz.openbmc_project.sdbusplus.Error.InvalidEnumString: " 97 "An enumeration mapping was attempted for which no valid enumeration " 98 "value exists."; 99 100 const char* name() const noexcept override; 101 const char* description() const noexcept override; 102 const char* what() const noexcept override; 103 int get_errno() const noexcept override; 104 }; 105 106 /** Exception for when unpackProperties cannot find given property in provided 107 * container */ 108 class UnpackPropertyError final : public internal_exception 109 { 110 public: 111 UnpackPropertyError(std::string_view propertyName, 112 const UnpackErrorReason reason); 113 114 static constexpr auto errName = 115 "xyz.openbmc_project.sdbusplus.Error.UnpackPropertyError"; 116 static constexpr auto errDesc = 117 "unpackProperties failed to unpack one of requested properties."; 118 static constexpr auto errWhat = 119 "xyz.openbmc_project.sdbusplus.Error.UnpackPropertyError: " 120 "unpackProperties failed to unpack one of requested properties."; 121 122 const char* name() const noexcept override; 123 const char* description() const noexcept override; 124 const char* what() const noexcept override; 125 int get_errno() const noexcept override; 126 127 const std::string propertyName; 128 const UnpackErrorReason reason; 129 130 private: 131 const std::string errWhatDetailed; 132 }; 133 134 class UnhandledStop final : public internal_exception 135 { 136 public: 137 static constexpr auto errName = 138 "xyz.openbmc_project.sdbusplus.Error.UnhandledStop"; 139 static constexpr auto errDesc = 140 "An async Sender failed to handle a stop condition."; 141 static constexpr auto errWhat = 142 "xyz.openbmc_project.sdbusplus.Error.UnhandledStop: " 143 "An async Sender failed to handle a stop condition."; 144 145 const char* name() const noexcept override; 146 const char* description() const noexcept override; 147 const char* what() const noexcept override; 148 int get_errno() const noexcept override; 149 }; 150 151 } // namespace exception 152 153 using exception_t = exception::exception; 154 using internal_exception_t = exception::internal_exception; 155 156 } // namespace sdbusplus 157