E2SAR 0.3.0
Loading...
Searching...
No Matches
e2sarError.hpp
1#ifndef E2SARERROR_HPP
2#define E2SARERROR_HPP
3
4#include <iostream>
5#include <string>
6#include <system_error>
7#include <boost/outcome.hpp>
8
9// this vodoo is based on this guide
10// https://www.boost.org/doc/libs/1_85_0/libs/outcome/doc/html/motivation/plug_error_code.html
11
17namespace outcome = BOOST_OUTCOME_V2_NAMESPACE;
18
19namespace e2sar
20{
21
23 enum class E2SARErrorc
24 {
25 NoError = 0,
26 CaughtException = 1,
27 ParseError = 2,
28 ParameterError = 3,
29 ParameterNotAvailable = 4,
30 OutOfRange = 5,
31 Undefined = 6,
32 NotFound = 7,
33 RPCError = 8,
34 SocketError = 9,
35 MemoryError = 10,
36 LogicError = 11,
37 SystemError = 12,
38 DataError = 13
39 };
40
42 {
43 E2SARErrorc ec;
44 std::string msg;
45
46 inline const E2SARErrorc code() const
47 {
48 return ec;
49 }
50
51 inline const std::string &message() const {
52 return msg;
53 }
54 };
55
56 // Localise an outcome implementation specific to this namespace.
57 template <class T>
58 using result = outcome::result<T, E2SARErrorInfo>;
59
62 {
63 private:
64 std::string _error_msg;
65
66 public:
67 E2SARException(const std::string &m) : _error_msg{m} {}
69 operator std::string() const
70 {
71 return "E2SAR exception: " + _error_msg;
72 }
73 operator std::string()
74 {
75 return _error_msg;
76 }
77
78 char *what() const noexcept
79 {
80 return const_cast<char *>(_error_msg.c_str());
81 }
82 };
83
84}
85
86namespace std
87{
88 // Tell the C++ 11 STL metaprogramming that enum
89 // is registered with the standard error code system
90 template <>
91 struct is_error_code_enum<e2sar::E2SARErrorc> : true_type
92 {
93 };
94}
95
96namespace detail
97{
98 // Define a custom error code category derived from std::error_category
99 class E2SARErrorc_category : public std::error_category
100 {
101 public:
102 // Return a short descriptive name for the category
103 virtual const char *name() const noexcept override final { return "E2SARError"; }
104 // Return what each enum means in text
105 virtual std::string message(int c) const override final
106 {
107 switch (static_cast<e2sar::E2SARErrorc>(c))
108 {
109 case e2sar::E2SARErrorc::CaughtException:
110 return "caught an exception";
111 case e2sar::E2SARErrorc::ParseError:
112 return "parsing error";
113 case e2sar::E2SARErrorc::ParameterError:
114 return "parameter error";
115 case e2sar::E2SARErrorc::ParameterNotAvailable:
116 return "parameter not available";
117 case e2sar::E2SARErrorc::OutOfRange:
118 return "value out of range";
119 case e2sar::E2SARErrorc::Undefined:
120 return "value undefined";
121 case e2sar::E2SARErrorc::NotFound:
122 return "file not found";
123 case e2sar::E2SARErrorc::RPCError:
124 return "gRPC error";
125 case e2sar::E2SARErrorc::SocketError:
126 return "socket error";
127 case e2sar::E2SARErrorc::MemoryError:
128 return "memory error";
129 case e2sar::E2SARErrorc::LogicError:
130 return "logic error";
131 case e2sar::E2SARErrorc::SystemError:
132 return "system error";
133 case e2sar::E2SARErrorc::DataError:
134 return "data error";
135 default:
136 return "unknown";
137 }
138 }
139
140 /*
141 // Allow generic error conditions to be compared to me
142 virtual std::error_condition default_error_condition(int c) const noexcept override final
143 {
144 switch (static_cast<e2sar::E2SARErrorc>(c))
145 {
146 case e2sar::E2SARErrorc::ParameterError:
147 return make_error_condition(std::errc::invalid_argument);
148 default:
149 // I have no mapping for this code
150 return std::error_condition(c, *this);
151 }
152 }
153 */
154 };
155}
156
157// Define the linkage for this function to be used by external code.
158// This would be the usual __declspec(dllexport) or __declspec(dllimport)
159// if we were in a Windows DLL etc. But for this example use a global
160// instance but with inline linkage so multiple definitions do not collide.
161#define THIS_MODULE_API_DECL extern inline
162
163// Declare a global function returning a static instance of the custom category
164THIS_MODULE_API_DECL const detail::E2SARErrorc_category &E2SARErrorc_category()
165{
167 return c;
168}
169
170namespace e2sar
171{
172 // Overload the global make_error_code() free function with our
173 // custom enum. It will be found via ADL by the compiler if needed.
174 // inline const std::error_code &make_error_code(const E2SARErrorInfo &ei) { return ei.ec; }
175
176 // make a STANDARD error code from our internal error code by adding custom category
177 inline std::error_code make_error_code(e2sar::E2SARErrorc e)
178 {
179 return {static_cast<int>(e), E2SARErrorc_category()};
180 }
181
182 // make an error code from error info with our custom category
183 inline std::error_code make_error_code(E2SARErrorInfo e)
184 {
185 return {static_cast<int>(e.ec), E2SARErrorc_category()};
186 }
187
188 // need to know how to make an exception pointer, but since we don't know
189 // how to make one, we just assume it knows how to make it from a custom error code
190 inline boost::exception_ptr make_exception_ptr(E2SARErrorInfo e)
191 {
192 return make_exception_ptr(make_error_code(e));
193 }
194}
195/*
196How to use:
197
198int main(void)
199{
200 // Note that we can now supply ConversionErrc directly to error_code
201 std::error_code ec = ConversionErrc::IllegalChar;
202
203 std::cout << "ConversionErrc::IllegalChar is printed by std::error_code as "
204 << ec << " with explanatory message " << ec.message() << std::endl;
205
206 // We can compare ConversionErrc containing error codes to generic conditions
207 std::cout << "ec is equivalent to std::errc::invalid_argument = "
208 << (ec == std::errc::invalid_argument) << std::endl;
209 std::cout << "ec is equivalent to std::errc::result_out_of_range = "
210 << (ec == std::errc::result_out_of_range) << std::endl;
211 return 0;
212}
213*/
214#endif
Definition e2sarError.hpp:100
Definition e2sarError.hpp:62
Definition e2sar.hpp:11
E2SARErrorc
Definition e2sarError.hpp:24
Definition e2sarError.hpp:42