xref: /openbmc/sdbusplus/src/exception.cpp (revision 0c8136a4)
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