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