xref: /openbmc/sdbusplus/src/exception.cpp (revision b6f729d6)
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 int exception::get_errno() const noexcept
18 {
19     return EIO;
20 }
21 
22 SdBusError::SdBusError(int error, const char* prefix, SdBusInterface* intf) :
23     error(SD_BUS_ERROR_NULL), intf(intf)
24 {
25     // We can't check the output of intf->sd_bus_error_set_errno() because
26     // it returns the input errorcode. We don't want to try and guess
27     // possible error statuses. Instead, check to see if the error was
28     // constructed to determine success.
29     intf->sd_bus_error_set_errno(&this->error, error);
30     if (!intf->sd_bus_error_is_set(&this->error))
31     {
32         throw std::runtime_error("Failed to create SdBusError");
33     }
34 
35     populateMessage(prefix);
36 }
37 
38 SdBusError::SdBusError(sd_bus_error* error, const char* prefix,
39                        SdBusInterface* intf) :
40     error(*error),
41     intf(intf)
42 {
43     // We own the error so remove the caller's reference
44     *error = SD_BUS_ERROR_NULL;
45 
46     populateMessage(prefix);
47 }
48 
49 SdBusError::SdBusError(SdBusError&& other) : error(SD_BUS_ERROR_NULL)
50 {
51     move(std::move(other));
52 }
53 
54 SdBusError& SdBusError::operator=(SdBusError&& other)
55 {
56     if (this != &other)
57     {
58         move(std::move(other));
59     }
60     return *this;
61 }
62 
63 SdBusError::~SdBusError()
64 {
65     intf->sd_bus_error_free(&error);
66 }
67 
68 const char* SdBusError::name() const noexcept
69 {
70     return error.name;
71 }
72 
73 const char* SdBusError::description() const noexcept
74 {
75     return error.message;
76 }
77 
78 const char* SdBusError::what() const noexcept
79 {
80     return full_message.c_str();
81 }
82 
83 int SdBusError::get_errno() const noexcept
84 {
85     return intf->sd_bus_error_get_errno(&this->error);
86 }
87 
88 const sd_bus_error* SdBusError::get_error() const noexcept
89 {
90     return &error;
91 }
92 
93 void SdBusError::populateMessage(const char* prefix)
94 {
95     full_message = prefix;
96     if (error.name)
97     {
98         full_message += ": ";
99         full_message += error.name;
100     }
101     if (error.message)
102     {
103         full_message += ": ";
104         full_message += error.message;
105     }
106 }
107 
108 void SdBusError::move(SdBusError&& other)
109 {
110     intf = std::move(other.intf);
111 
112     intf->sd_bus_error_free(&error);
113     error = other.error;
114     other.error = SD_BUS_ERROR_NULL;
115 
116     full_message = std::move(other.full_message);
117 }
118 
119 const char* InvalidEnumString::name() const noexcept
120 {
121     return errName;
122 }
123 
124 const char* InvalidEnumString::description() const noexcept
125 {
126     return errDesc;
127 }
128 
129 const char* InvalidEnumString::what() const noexcept
130 {
131     return errWhat;
132 }
133 
134 UnpackPropertyError::UnpackPropertyError(std::string_view propertyName,
135                                          std::string_view reason) :
136     propertyName(propertyName),
137     reason(reason)
138 {}
139 
140 const char* UnpackPropertyError::name() const noexcept
141 {
142     return errName;
143 }
144 
145 const char* UnpackPropertyError::description() const noexcept
146 {
147     return errDesc;
148 }
149 
150 const char* UnpackPropertyError::what() const noexcept
151 {
152     return errWhat;
153 }
154 
155 } // namespace exception
156 } // namespace sdbusplus
157 
158 #ifdef __clang__
159 #pragma clang diagnostic pop
160 #endif
161