rad  5.1.0
exceptions.hpp
Go to the documentation of this file.
1 
9 #ifndef RAD_EXCEPTIONS_HPP
10 #define RAD_EXCEPTIONS_HPP
11 
12 #include <rad/helper.hpp>
13 #include <rad/logger.hpp>
14 
15 #include <boost/stacktrace.hpp>
16 #include <boost/filesystem.hpp>
17 #include <boost/core/demangle.hpp>
18 
19 #include <exception>
20 #include <string>
21 #include <vector>
22 #include <memory>
23 #include <ostream>
24 #include <chrono>
25 #include <thread>
26 #include <type_traits>
27 
28 
29 namespace rad {
30 
53 class Exception : public std::exception {
54  public:
66  typedef std::chrono::system_clock clock_t;
67 
73  explicit Exception(const std::string& message);
74 
75  explicit Exception(const std::string& message, const std::string& info);
76 
80  virtual ~Exception() = default;
81 
87  const boost::stacktrace::stacktrace& GetStackTrace() const;
88 
94  const boost::stacktrace::stacktrace& GetOriginalStackTrace() const;
95 
101  std::string GetStackTraceAsString() const;
102 
108  std::string GetOriginalStackTraceAsString() const;
109 
115  std::string GetFullStackTraceAsString() const;
116 
122  std::chrono::time_point<clock_t> GetTimePoint() const;
123 
129  int64_t GetCreationDate() const;
130 
136  std::thread::id GetThreadId() const;
137 
143  int GetProcessId() const;
144 
150  std::string GetHostName() const;
151 
152 
158  std::string GetTypeName() const;
159 
165  void SetLineNumber(uint32_t line_number);
166 
172  uint32_t GetLineNumber() const;
173 
179  void SetFunctionName(const std::string& function_name);
180 
186  const std::string& GetFunctionName() const;
187 
193  void SetFileName(const std::string& file_name);
194 
200  const std::string& GetFileName() const;
201 
207  void SetDetails(const std::string& details);
208 
214  std::string GetDetails() const;
215 
221  void SetClassName(const std::string& class_name);
222 
228  void SetExceptionStack(const std::vector<std::string>& nested_exceptions);
229 
235  std::vector<std::string> GetExceptionStack() const;
236 
242  std::string Dump() const;
243 
251  std::string DumpWithNested() const;
252 
256  virtual const char* what() const noexcept override;
257 
258  private:
265  const std::string AdditionalDetails() const;
266 
267  /*
268  * Attributes wrapper
269  */
270  struct Attrs {
271  boost::stacktrace::stacktrace stack_trace;
272  std::chrono::time_point<clock_t> date_time;
273  std::thread::id thread_id;
274  uint32_t line_number;
275  std::string function_name;
276  std::string file_name;
277  std::string details;
278  bool detail_set_by_user;
279  std::string class_name;
280  std::string message;
281  std::vector<std::string> exception_stack;
282  };
283 
284  std::shared_ptr<Attrs> m_attrs;
285 };
286 
287 
288 namespace {
289 
290 template <typename T>
291 T CreateExceptionWithMessage(const char* file, int line, const char* function,
292  const std::string& msg) {
293  std::string fullmsg = msg;
294  fullmsg += "\nSource file: " + std::string(file);
295  fullmsg += "\nLine no.: " + std::to_string(line);
296  fullmsg += "\nFunction: " + std::string(function);
297  return T(fullmsg);
298 }
299 
300 template <typename T, typename N>
301 T CreateExceptionObject(const N& nested_exception, const char* file, int line,
302  const char* function, const std::string& msg) {
303  if constexpr (std::is_base_of_v<Exception, T>) {
304  T throwing_exception = T(msg);
305  throwing_exception.SetFileName(boost::filesystem::path(file).filename().string());
306  throwing_exception.SetFunctionName(function);
307  throwing_exception.SetLineNumber(line);
308  throwing_exception.SetClassName(boost::core::demangle(typeid(T).name()));
309  std::vector<std::string> this_stack;
310  this_stack.push_back(throwing_exception.GetTypeName());
311  if constexpr (std::is_base_of_v<Exception, N>) {
312  //std::vector<std::string> nested_stack = nested_exception.getCiiExceptionStack();
313  std::vector<std::string> nested_stack = nested_exception.GetExceptionStack();
314  this_stack.insert(this_stack.end(), nested_stack.begin(), nested_stack.end());
315  }
316  //throwing_exception.SetCiiExceptionStack(this_stack);
317  throwing_exception.SetExceptionStack(this_stack);
318  return throwing_exception;
319  } else if constexpr (std::is_base_of_v<std::runtime_error, T> or
320  std::is_base_of_v<std::logic_error, T>) {
321  return CreateExceptionWithMessage<T>(file, line, function, msg);
322  } else {
323  return T(msg);
324  }
325 }
326 
327 } // namespace anonymous
328 
334 #define RAD_THROW(exceptionType_t, msg) { \
335  throw rad::CreateExceptionObject<exceptionType_t>(0, __FILE__, __LINE__, __FUNCTION__, \
336  msg); \
337 }
338 
345 #define RAD_RETHROW(exceptionType_t, nested_exception, msg) { \
346  exceptionType_t throwing_exception = rad::CreateExceptionObject<exceptionType_t>( \
347  nested_exception, __FILE__, __LINE__, __FUNCTION__, msg); \
348  std::throw_with_nested(throwing_exception); \
349 }
350 
356 #define RAD_LOG_THROW(exceptionType_t, logger, msg) { \
357  LOG4CPLUS_ERROR(logger, msg); \
358  throw rad::CreateExceptionObject<exceptionType_t>(0, __FILE__, __LINE__, __FUNCTION__, \
359  msg); \
360 }
361 
362 std::ostream& operator<<(std::ostream& os, const rad::Exception& e);
363 
364 } // namespace rad
365 
366 #endif // RAD_EXCEPTIONS_HPP
Base class for the exceptions thrown by RAD and its users.
Definition: exceptions.hpp:53
std::string GetOriginalStackTraceAsString() const
Same as GetOriginalStackTrace() but convert the trace to a string.
Definition: exceptions.cpp:70
std::string GetHostName() const
Return the name of the host in which the exception was created.
Definition: exceptions.cpp:115
std::string GetDetails() const
Get the exception details.
Definition: exceptions.cpp:162
uint32_t GetLineNumber() const
Return the line number in which the exception was thrown.
Definition: exceptions.cpp:137
int GetProcessId() const
Return the id of the process in which the exception was created.
Definition: exceptions.cpp:111
std::string GetFullStackTraceAsString() const
Return the full stack trace (including nested exceptions)
Definition: exceptions.cpp:76
std::string GetTypeName() const
Return the exception class name.
Definition: exceptions.cpp:119
const boost::stacktrace::stacktrace & GetOriginalStackTrace() const
Return the stack trace captured in the most nested exception constructor.
Definition: exceptions.cpp:49
std::string GetStackTraceAsString() const
Same as GetStackTrace() but convert the trace to a string.
Definition: exceptions.cpp:64
std::vector< std::string > GetExceptionStack() const
Retrieves the nested exception stack as string.
Definition: exceptions.cpp:176
void SetFileName(const std::string &file_name)
Set the name of the file in which the exception was thrown.
Definition: exceptions.cpp:149
Exception(const std::string &message)
Constructor.
Definition: exceptions.cpp:25
std::chrono::time_point< clock_t > GetTimePoint() const
Return the exception creation time as a chrono timepoint.
Definition: exceptions.cpp:97
std::string Dump() const
Return the exception's details.
Definition: exceptions.cpp:180
std::chrono::system_clock clock_t
The clock to use for determining the exception creation time.
Definition: exceptions.hpp:66
void SetClassName(const std::string &class_name)
Set the name of the class in which the exception was thrown.
Definition: exceptions.cpp:168
virtual const char * what() const noexcept override
Return the exception message.
Definition: exceptions.cpp:221
const std::string & GetFunctionName() const
Return the name of the function in which the exception was thrown.
Definition: exceptions.cpp:145
void SetDetails(const std::string &details)
Set the exception details.
Definition: exceptions.cpp:157
const boost::stacktrace::stacktrace & GetStackTrace() const
Return the stack trace captured in the exception constructor.
Definition: exceptions.cpp:45
void SetFunctionName(const std::string &function_name)
Set the name of the function in which the exception was thrown.
Definition: exceptions.cpp:141
std::string DumpWithNested() const
Return all the exception's details including details of nested exceptions.
Definition: exceptions.cpp:201
void SetLineNumber(uint32_t line_number)
Set the line number in which the exception was thrown.
Definition: exceptions.cpp:123
virtual ~Exception()=default
Destructor.
void SetExceptionStack(const std::vector< std::string > &nested_exceptions)
Set the nested exceptions as strings.
Definition: exceptions.cpp:172
std::thread::id GetThreadId() const
Return the id of the thread in which the exception was created.
Definition: exceptions.cpp:107
const std::string & GetFileName() const
Return the name of the file in which the exception was thrown.
Definition: exceptions.cpp:153
int64_t GetCreationDate() const
Return the exception creation time as number of seconds since Unix Epoch.
Definition: exceptions.cpp:101
Logger class.
Helper class header file.
Definition: actionsApp.cpp:20
std::ostream & operator<<(std::ostream &os, const rad::Exception &e)
Definition: exceptions.cpp:225
Definition: errors.hpp:58
name
Definition: wscript:8