ADTF
ucom3/include/adtfucom3/exception_handling.h
Go to the documentation of this file.
1 
7 #pragma once
8 
9 #include <a_utils.h>
10 #include <string>
11 #include <sstream>
12 #include <exception>
13 
14 namespace adtf
15 {
16 namespace ucom
17 {
18 namespace kiwi
19 {
20 
21 std::string nested_exceptions_to_string(const std::exception& error);
22 
23 namespace detail
24 {
25 
26 inline void format_nested_exception(const std::exception& error, std::ostream& stream, bool add_line_break = false)
27 {
28  try
29  {
30  std::rethrow_if_nested(error);
31  }
32  catch (const std::exception& nested_exception)
33  {
34  format_nested_exception(nested_exception, stream, true);
35  }
36  catch (...)
37  {
38  }
39 
40  stream << "exception: " << error.what();
41  if (add_line_break)
42  {
43  stream << '\n';
44  }
45 }
46 
47 inline tResult annotate_result(const tResult& oOriginal,
48  const char* strFile,
49  int nLine,
50  const char* strFunction,
51  const tChar* strDescription = "")
52 {
53  std::ostringstream strAnnotatedDescription;
54  strAnnotatedDescription << oOriginal.GetDescription()
55  << " ["
56  << adtf::util::cFilename(oOriginal.GetFile()).GetName().GetPtr() << ":"
57  << oOriginal.GetLine()
58  << "(" << oOriginal.GetFunction() << ")]\n"
59  << strDescription;
60 
61  return tResult(oOriginal.GetErrorCode(),
62  strAnnotatedDescription.str().c_str(),
63  nLine,
64  adtf::util::detail::filename_with_thread_id(strFile).c_str(),
65  strFunction);
66 }
67 
68 inline tResult current_exception_to_result(const char* file, size_t line, const char* function)
69 {
70  auto exception = std::current_exception();
71  try
72  {
73  if (exception)
74  {
75  std::rethrow_exception(exception);
76  }
77  }
78  catch(const std::exception& error)
79  {
80  return tResult(ERR_FAILED,
82  static_cast<int32_t>(line),
83  adtf::util::cFilename(file).GetName(),
84  function);
85  }
86  catch(const tResult& oError)
87  {
88  return annotate_result(oError, file, static_cast<int32_t>(line), function);
89  }
90  catch(...)
91  {
92  return tResult(ERR_FAILED,
93  "unknown exception",
94  static_cast<int32_t>(line),
95  file,
96  function);
97  }
98 
100 }
101 
102 
103 
104 }
105 
111 inline std::string nested_exceptions_to_string(const std::exception& error)
112 {
113  std::ostringstream stream;
114  detail::format_nested_exception(error, stream);
115  return stream.str();
116 }
117 
123 inline std::string current_exception_to_string()
124 {
125  auto exception = std::current_exception();
126  try
127  {
128  if (exception)
129  {
130  std::rethrow_exception(exception);
131  }
132  }
133  catch(const std::exception& error)
134  {
135  return nested_exceptions_to_string(error);
136  }
137  catch(const tResult& oError)
138  {
139  return adtf::util::to_string(oError).GetPtr();
140  }
141  catch(...)
142  {
143  return "unknown exception";
144  }
145 
146  return "";
147 }
148 
155 {
156  return detail::current_exception_to_result(__FILE__, __LINE__, __FUNC__);
157 }
158 
159 }
160 
164 
165 }
166 }
167 
169 #define ADTF_UCOM_ANNOTATE_RESULT(_result) adtf::ucom::kiwi::detail::annotate_result(_result, __FILE__, __LINE__, __FUNC__)
170 
172 #define ADTF_UCOM_COMPOSED_RESULT(_result, ...) adtf::ucom::kiwi::detail::annotate_result(_result, __FILE__, __LINE__, __FUNC__, adtf::util::cString::Format(__VA_ARGS__).GetPtr())
173 
175 #define THROW_ERROR_DESC(_code, ...) throw DETAILED_RESULT(_code, __VA_ARGS__)
177 #define THROW_IF_FAILED(s) { tResult _errcode(s); if ( _errcode.IsFailed() ) { throw ADTF_UCOM_ANNOTATE_RESULT(_errcode); } }
179 #define THROW_IF_FAILED_DESC(s, ...) { tResult _errcode(s); if ( _errcode.IsFailed() ) { throw ADTF_UCOM_COMPOSED_RESULT(_errcode, __VA_ARGS__); } }
180 
182 #define RETURN_CURRENT_EXCEPTION() return adtf::ucom::kiwi::detail::current_exception_to_result(__FILE__, __LINE__, __FUNC__)
184 #define RETURN_CURRENT_EXCEPTION_DESC(...) return ADTF_UCOM_COMPOSED_RESULT(adtf::ucom::kiwi::detail::current_exception_to_result(__FILE__, __LINE__, __FUNC__), __VA_ARGS__)
185 
187 #define RETURN_IF_THROWS(s) { try { (s); } catch(...) { RETURN_CURRENT_EXCEPTION(); } }
189 #define RETURN_IF_THROWS_DESC(s, ...) { try { (s); } catch(...) { RETURN_CURRENT_EXCEPTION_DESC(__VA_ARGS__); } }
190 
191 // redefine RETURN_IF_FAILED macros in order to catch exceptions and retain the previous error description(s)
192 #ifdef RETURN_IF_FAILED
193  #undef RETURN_IF_FAILED
194 #endif
196 #define RETURN_IF_FAILED(s) { try { tResult _errcode(s); if ( _errcode.IsFailed() ) { return ADTF_UCOM_ANNOTATE_RESULT(_errcode); } } catch (...) { RETURN_CURRENT_EXCEPTION(); } }
197 
198 #ifdef RETURN_IF_FAILED_DESC
199  #undef RETURN_IF_FAILED_DESC
200 #endif
202 #define RETURN_IF_FAILED_DESC(s, ...) { try { tResult _errcode(s); if ( _errcode.IsFailed() ) { return ADTF_UCOM_COMPOSED_RESULT(_errcode, __VA_ARGS__); } } catch (...) { RETURN_CURRENT_EXCEPTION_DESC(__VA_ARGS__); } }
Copyright © Audi Electronics Venture GmbH.
char tChar
The tChar defines the type for platform character set (platform and compiler dependent type).
A_UTILS_NS::cResult tResult
For backwards compatibility and to bring latest version into scope.
#define RETURN_NOERROR
Return status ERR_NOERROR, which requires the calling function's return type to be tResult.
const tChar * GetDescription() const noexcept
Get user provided error description.
tErrorCode GetErrorCode() const noexcept
Get error code.
tInt32 GetLine() const noexcept
Get line in source file where the error was reported.
const tChar * GetFunction() const noexcept
Get name of the function the error was reported in.
const tChar * GetFile() const noexcept
Get name of the file the error was reported in.
tResult current_exception_to_result()
Converts the current exception object into a tResult.
std::string nested_exceptions_to_string(const std::exception &error)
Formats nested std::exceptions into a string, line by line.
std::string current_exception_to_string()
Trys to format the current exception into a string.
Namespace for entire ADTF SDK.