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  const auto strOriginalDescription = oOriginal.GetDescription();
54 
55 
56 
57  const auto strAnnotatedDescription = adtf::util::cString::Format("%s [%s:%d(%s)]\n%s",
58  strOriginalDescription,
59  adtf::util::cFilename(oOriginal.GetFile()).GetName().GetPtr(),
60  oOriginal.GetLine(),
61  oOriginal.GetFunction(),
62  strDescription);
63 
64  return tResult(oOriginal.GetErrorCode(),
65  strAnnotatedDescription,
66  nLine,
67  adtf::util::cFilename(strFile).GetName().GetPtr(),
68  strFunction);
69 }
70 
71 inline tResult current_exception_to_result(const char* file, size_t line, const char* function)
72 {
73  auto exception = std::current_exception();
74  try
75  {
76  if (exception)
77  {
78  std::rethrow_exception(exception);
79  }
80  }
81  catch(const std::exception& error)
82  {
83  return tResult(ERR_FAILED,
85  static_cast<int32_t>(line),
86  adtf::util::cFilename(file).GetName(),
87  function);
88  }
89  catch(const tResult& oError)
90  {
91  return annotate_result(oError, file, static_cast<int32_t>(line), function);
92  }
93  catch(...)
94  {
95  return tResult(ERR_FAILED,
96  "unknown exception",
97  static_cast<int32_t>(line),
98  file,
99  function);
100  }
101 
103 }
104 
105 
106 
107 }
108 
114 inline std::string nested_exceptions_to_string(const std::exception& error)
115 {
116  std::ostringstream stream;
117  detail::format_nested_exception(error, stream);
118  return stream.str();
119 }
120 
126 inline std::string current_exception_to_string()
127 {
128  auto exception = std::current_exception();
129  try
130  {
131  if (exception)
132  {
133  std::rethrow_exception(exception);
134  }
135  }
136  catch(const std::exception& error)
137  {
138  return nested_exceptions_to_string(error);
139  }
140  catch(const tResult& oError)
141  {
142  return adtf::util::to_string(oError).GetPtr();
143  }
144  catch(...)
145  {
146  return "unknown exception";
147  }
148 
149  return "";
150 }
151 
158 {
159  return detail::current_exception_to_result(__FILE__, __LINE__, __FUNC__);
160 }
161 
162 }
163 
167 
168 }
169 }
170 
172 #define ADTF_UCOM_ANNOTATE_RESULT(_result) adtf::ucom::kiwi::detail::annotate_result(_result, __FILE__, __LINE__, __FUNC__)
173 
175 #define ADTF_UCOM_COMPOSED_RESULT(_result, ...) adtf::ucom::kiwi::detail::annotate_result(_result, __FILE__, __LINE__, __FUNC__, adtf::util::cString::Format(__VA_ARGS__).GetPtr())
176 
178 #define THROW_ERROR_DESC(_code, ...) throw DETAILED_RESULT(_code, __VA_ARGS__)
180 #define THROW_IF_FAILED(s) { tResult _errcode(s); if ( _errcode.IsFailed() ) { throw ADTF_UCOM_ANNOTATE_RESULT(_errcode); } }
182 #define THROW_IF_FAILED_DESC(s, ...) { tResult _errcode(s); if ( _errcode.IsFailed() ) { throw ADTF_UCOM_COMPOSED_RESULT(_errcode, __VA_ARGS__); } }
183 
185 #define RETURN_CURRENT_EXCEPTION() return adtf::ucom::kiwi::detail::current_exception_to_result(__FILE__, __LINE__, __FUNC__)
187 #define RETURN_CURRENT_EXCEPTION_DESC(...) return ADTF_UCOM_COMPOSED_RESULT(adtf::ucom::kiwi::detail::current_exception_to_result(__FILE__, __LINE__, __FUNC__), __VA_ARGS__)
188 
190 #define RETURN_IF_THROWS(s) { try { (s); } catch(...) { RETURN_CURRENT_EXCEPTION(); } }
192 #define RETURN_IF_THROWS_DESC(s, ...) { try { (s); } catch(...) { RETURN_CURRENT_EXCEPTION_DESC(__VA_ARGS__); } }
193 
194 // redefine RETURN_IF_FAILED macros in order to catch exceptions and retain the previous error description(s)
195 #ifdef RETURN_IF_FAILED
196  #undef RETURN_IF_FAILED
197 #endif
199 #define RETURN_IF_FAILED(s) { try { tResult _errcode(s); if ( _errcode.IsFailed() ) { return ADTF_UCOM_ANNOTATE_RESULT(_errcode); } } catch (...) { RETURN_CURRENT_EXCEPTION(); } }
200 
201 #ifdef RETURN_IF_FAILED_DESC
202  #undef RETURN_IF_FAILED_DESC
203 #endif
205 #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
Get user provided error description.
tInt32 GetLine() const
Get line in source file where the error was reported.
tErrorCode GetErrorCode() const
Get error code.
const tChar * GetFunction() const
Get name of the function the error was reported in.
const tChar * GetFile() const
Get name of the file the error was reported in.
const tChar * GetPtr() const
This function returns the current string as an array of characters (c-style)
Definition: string.h:473
cString to_string(const tResult &i_oResult, eResultFormatFlags i_eFormatFlags=eResultFormatFlags::RFF_DisableNone, const tChar *i_strFormat=nullptr)
Copy all information of an assigned result object to a (formatted) string.
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.