Compute Graph Framework SDK Reference
5.4.5418 Release
For Test and Development only

Exception.hpp
Go to the documentation of this file.
1 //
3 // Notice
4 // ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
5 // NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
6 // THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
7 // MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 //
9 // NVIDIA CORPORATION & AFFILIATES assumes no responsibility for the consequences of use of such
10 // information or for any infringement of patents or other rights of third parties that may
11 // result from its use. No license is granted by implication or otherwise under any patent
12 // or patent rights of NVIDIA CORPORATION & AFFILIATES. No third party distribution is allowed unless
13 // expressly authorized by NVIDIA. Details are subject to change without notice.
14 // This code supersedes and replaces all information previously supplied.
15 // NVIDIA CORPORATION & AFFILIATES products are not authorized for use as critical
16 // components in life support devices or systems without express written approval of
17 // NVIDIA CORPORATION & AFFILIATES.
18 //
19 // SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
20 // SPDX-License-Identifier: LicenseRef-NvidiaProprietary
21 //
22 // NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
23 // property and proprietary rights in and to this material, related
24 // documentation and any modifications thereto. Any use, reproduction,
25 // disclosure or distribution of this material and related documentation
26 // without an express license agreement from NVIDIA CORPORATION or
27 // its affiliates is strictly prohibited.
28 //
30 
31 #ifndef DW_FRAMEWORK_EXCEPTION_HPP_
32 #define DW_FRAMEWORK_EXCEPTION_HPP_
33 
34 #include <dwcgf/logger/Logger.hpp>
35 #include <dw/core/base/ExceptionWithStackTrace.hpp>
36 #include <dw/core/base/Status.h>
37 #include <dw/core/container/BaseString.hpp>
38 #include <nvscierror.h>
39 
40 #define THROW_ON_PARAM_NULL(param) \
41  if (param == nullptr) \
42  { \
43  throw dw::framework::Exception(DW_INVALID_ARGUMENT, #param " == nullptr ", DW_FUNCTION_NAME, ":", __LINE__); \
44  }
45 
46 namespace dw
47 {
48 namespace framework
49 {
50 
52 
53 class Exception : public dw::core::ExceptionBase
54 {
55 public:
56  static constexpr char8_t LOG_TAG[] = "Exception";
57 
58  Exception(dwStatus statusCode, const char8_t* messageStr)
59  : dw::core::ExceptionBase(dwGetStatusName(statusCode))
60  , m_statusCode(statusCode)
61  , m_messageBegin(0)
62  {
63  m_what += ": ";
64  m_messageBegin = m_what.length();
65  m_what += messageStr;
66  }
67 
68  ~Exception() noexcept override = default;
69 
71  // These templated constructors allow direct construction of the message
72  template <class... Tothers>
73  explicit Exception(dwStatus statusCode, const char8_t* messageStr, Tothers... others)
74  : Exception(statusCode, messageStr)
75  {
76  (void)std::initializer_list<int32_t>{(static_cast<void>(m_what << others), 0)...};
77  }
78 
79  dwStatus status() const
80  {
81  return m_statusCode;
82  }
83 
84  char8_t const* messageStr() const noexcept
85  {
86  return what() + m_messageBegin;
87  }
88 
101  template <typename TryBlock>
102  static dwStatus guardWithReturn(TryBlock tryBlock);
103 
108  template <typename TryBlock>
109  static dwStatus guard(TryBlock tryBlock);
110 
111  template <typename TryBlock>
112  static dwStatus guardWithNoPrint(TryBlock tryBlock);
113 
114 private:
115  dwStatus m_statusCode;
116  size_t m_messageBegin;
117 };
118 
120 // Cannot compile with NVCC because of the generic lambda
121 template <typename TryBlock>
122 dwStatus Exception::guardWithReturn(TryBlock tryBlock)
123 {
124  using FixedString = dw::core::BaseString<40>;
125 
126  // logging exception
127  auto const logException = [](const dwStatus status, const auto& ex, FixedString errorMessage) -> dwStatus {
128 
129  // Disabling rule A5-1-1 here as literals are allowed for logging
130  // coverity[autosar_cpp14_a5_1_1_violation]
131  DW_LOGD << errorMessage
132  << dwGetStatusName(status)
133  << ", "
134  << ex.what()
135  << Logger::State::endl
136  << ex.stackTrace()
137  << Logger::State::endl;
138 
139  return status;
140  };
141 
142  try
143  {
144  return tryBlock();
145  }
146  catch (const Exception& ex)
147  {
148  // TODO(lindax): Make this message a warning after RR1.0 fix all their
149  // channel problem
150 
151  DW_LOGD << "Framework exception thrown: "
152  << dwGetStatusName(ex.status())
153  << ", "
154  << ex.what()
155  << Logger::State::endl;
156  return ex.status();
157  }
158  catch (const BufferFullException& ex)
159  {
160  // Disabling rule A4-5-1 here. Coverity confuses 'status' used as parameter in lambda function with using enum as operand in overloaded "operator ()"
161  // coverity[autosar_cpp14_a4_5_1_violation]
162 
163  return logException(DW_BUFFER_FULL, ex, FixedString("Framework exception thrown: "));
164  }
165  catch (const BufferEmptyException& ex)
166  {
167  // Disabling rule A4-5-1 here. Coverity confuses 'status' used as parameter in lambda function with using enum as operand in overloaded "operator ()"
168  // coverity[autosar_cpp14_a4_5_1_violation]
169  return logException(DW_NOT_AVAILABLE, ex, FixedString("Framework exception thrown: "));
170  }
171  catch (const OutOfBoundsException& ex)
172  {
173  // Disabling rule A4-5-1 here. Coverity confuses 'status' used as parameter in lambda function with using enum as operand in overloaded "operator ()"
174  // coverity[autosar_cpp14_a4_5_1_violation]
175  return logException(DW_OUT_OF_BOUNDS, ex, FixedString("Framework exception thrown: "));
176  }
177  catch (const InvalidArgumentException& ex)
178  {
179  // Disabling rule A4-5-1 here. Coverity confuses 'status' used as parameter in lambda function with using enum as operand in overloaded "operator ()"
180  // coverity[autosar_cpp14_a4_5_1_violation]
181  return logException(DW_INVALID_ARGUMENT, ex, FixedString("Framework exception thrown: "));
182  }
183  catch (const BadAlignmentException& ex)
184  {
185  // Disabling rule A4-5-1 here. Coverity confuses 'status' used as parameter in lambda function with using enum as operand in overloaded "operator ()"
186  // coverity[autosar_cpp14_a4_5_1_violation]
187  return logException(DW_BAD_ALIGNMENT, ex, FixedString("Framework exception thrown: "));
188  }
189  catch (const CudaException& ex)
190  {
191  // Disabling rule A4-5-1 here. Coverity confuses 'status' used as parameter in lambda function with using enum as operand in overloaded "operator ()"
192  // coverity[autosar_cpp14_a4_5_1_violation]
193  return logException(DW_CUDA_ERROR, ex, FixedString("Framework exception thrown: "));
194  }
195  catch (const ExceptionWithStackTrace& ex)
196  {
197  // Disabling rule A4-5-1 here. Coverity confuses 'status' used as parameter in lambda function with using enum as operand in overloaded "operator ()"
198  // coverity[autosar_cpp14_a4_5_1_violation]
199  return logException(DW_FAILURE, ex, FixedString("Framework exception thrown: "));
200  }
201  catch (const std::exception& ex)
202  {
203  // Disabling rule A4-5-1 here. Coverity confuses 'status' used as parameter in lambda function with using enum as operand in overloaded "operator ()"
204  // coverity[autosar_cpp14_a4_5_1_violation]
205 
206  DW_LOGD << "std::exception thrown: "
207  << dwGetStatusName(DW_FAILURE)
208  << ", "
209  << ex.what()
210  << Logger::State::endl;
211  return DW_FAILURE;
212  }
213  catch (...)
214  {
215  // Disabling rule A4-5-1 here. Coverity confuses 'status' used as parameter in lambda function with using enum as operand in overloaded "operator ()"
216  // coverity[autosar_cpp14_a4_5_1_violation]
217 
218  DW_LOGD << "Unknown exception thrown, "
219  << dwGetStatusName(DW_FAILURE)
220  << Logger::State::endl;
221 
222  return DW_FAILURE;
223  }
224 }
225 
227 template <typename TryBlock>
228 dwStatus Exception::guard(TryBlock tryBlock)
229 {
230  static_assert(std::is_same<void, typename std::result_of<TryBlock()>::type>::value,
231  "tryBlock must return void");
232 
233  return guardWithReturn([&] {
234  tryBlock();
235  return DW_SUCCESS;
236  });
237 }
238 
240 template <typename TryBlock>
241 dwStatus Exception::guardWithNoPrint(TryBlock tryBlock)
242 {
243  try
244  {
245  tryBlock();
246  return DW_SUCCESS;
247  }
248  catch (const Exception& ex)
249  {
250  return ex.status();
251  }
252 }
253 
254 const char* nvSciGetEventName(uint32_t event);
255 const char* nvSciGetErrorName(uint32_t error);
256 
257 } // namespace framework
258 } // namespace dw
259 
260 //------------------------------------------------------------------------------
261 // macro to easily check for dw errors
262 #define FRWK_CHECK_DW_ERROR(x) \
263  { \
264  dwStatus result = x; \
265  if (result != DW_SUCCESS) \
266  { \
267  throw dw::framework::Exception(result, "DriveWorks Error"); \
268  } \
269  };
270 #define GET_STRING(s) #s
271 #define FRWK_CHECK_DW_ERROR_IGNORE_SOME(x, fallback, ...) \
272  { \
273  dwStatus result = x; \
274  dwStatus ignoreErros[] = {__VA_ARGS__}; \
275  if (result != DW_SUCCESS) \
276  { \
277  if (std::find(std::begin(ignoreErros), std::end(ignoreErros), result) != std::end(ignoreErros)) \
278  { \
279  DW_LOGD << __FILE__ \
280  << "(" << __LINE__ << ") " \
281  << "Ignoring Error: " \
282  << dwGetStatusName(result) << ". Falling back on calling " << GET_STRING(fallback) \
283  << dw::core::Logger::State::endl; \
284  result = fallback; \
285  if (result != DW_SUCCESS) \
286  { \
287  throw dw::framework::Exception(result, "After ignoring errors from ignore list, fallback operation %s encountered DriveWorks error.", GET_STRING(fallback)); \
288  } \
289  } \
290  } \
291  if (result != DW_SUCCESS) \
292  { \
293  throw dw::framework::Exception(result, "DriveWorks error not in ignore list."); \
294  } \
295  };
296 
297 #define FRWK_CHECK_DW_ERROR_NOTHROW(x) \
298  { \
299  dwStatus result = x; \
300  if (result != DW_SUCCESS) \
301  { \
302  DW_LOGE << __FILE__ \
303  << "(" << __LINE__ << ") " \
304  << "DriveWorks exception but not thrown: " \
305  << dwGetStatusName(result) \
306  << dw::core::Logger::State::endl; \
307  } \
308  };
309 
310 #define FRWK_CHECK_DW_ERROR_MSG(x, description) \
311  { \
312  dwStatus result = (x); \
313  if (result != DW_SUCCESS) \
314  { \
315  throw dw::framework::Exception(result, (description)); \
316  } \
317  };
318 
319 //------------------------------------------------------------------------------
320 // macro to easily check for cuda errors
321 #define FRWK_CHECK_CUDA_ERROR(x) \
322  { \
323  x; \
324  auto result = cudaGetLastError(); \
325  if (result != cudaSuccess) \
326  { \
327  throw dw::framework::Exception(DW_CUDA_ERROR, cudaGetErrorString(result)); \
328  } \
329  };
330 
331 #define FRWK_CHECK_CUDA_ERROR_NOTHROW(x) \
332  { \
333  x; \
334  auto result = cudaGetLastError(); \
335  if (result != cudaSuccess) \
336  { \
337  DW_LOGE << __FILE__ \
338  << "(" << __LINE__ << ") " \
339  << "CUDA error but not thrown: " \
340  << cudaGetErrorString(result) \
341  << dw::core::Logger::State::endl; \
342  } \
343  };
344 
345 #define FRWK_CHECK_NVMEDIA_ERROR(e) \
346  { \
347  auto FRWK_CHECK_NVMEDIA_ERROR_ret = (e); \
348  if (FRWK_CHECK_NVMEDIA_ERROR_ret != NVMEDIA_STATUS_OK) \
349  { \
350  throw dw::framework::Exception(DW_NVMEDIA_ERROR, "NvMedia error occured"); \
351  } \
352  }
353 
354 #define FRWK_CHECK_NVSCI_ERROR(e) \
355  { \
356  auto FRWK_CHECK_NVSCI_ERROR_ret = (e); \
357  if (FRWK_CHECK_NVSCI_ERROR_ret != NvSciError_Success) \
358  { \
359  DW_LOGE << "Failed with " << nvSciGetErrorName(FRWK_CHECK_NVSCI_ERROR_ret) \
360  << "(" << FRWK_CHECK_NVSCI_ERROR_ret << ")" \
361  << " in " << __FILE__ \
362  << ":" << __LINE__ << Logger::State::endl; \
363  if (FRWK_CHECK_NVSCI_ERROR_ret == NvSciError_Timeout) \
364  throw Exception(DW_TIME_OUT, "NvSci API Timeout"); \
365  else \
366  throw Exception(DW_INTERNAL_ERROR, "NvSci internal error occured"); \
367  } \
368  }
369 
370 #endif // DW_FRAMEWORK_TYPES_HPP_
static dwStatus guardWithNoPrint(TryBlock tryBlock)
Definition: Exception.hpp:241
static dwStatus guardWithReturn(TryBlock tryBlock)
Simple try/catch handler to catch dw::core::Exception and return a dwStatus error code if the given f...
Definition: Exception.hpp:122
Exception(dwStatus statusCode, const char8_t *messageStr)
Definition: Exception.hpp:58
char8_t const * messageStr() const noexcept
Definition: Exception.hpp:84
dwStatus status() const
Definition: Exception.hpp:79
Exception(dwStatus statusCode, const char8_t *messageStr, Tothers... others)
Definition: Exception.hpp:73
static dwStatus guard(TryBlock tryBlock)
Same as previous guard but with a simpler tryBlock with signature &#39;void tryBlock()&#39; Always returns DW...
Definition: Exception.hpp:228
const char * nvSciGetEventName(uint32_t event)
static constexpr char8_t LOG_TAG[]
Definition: Exception.hpp:56
Definition: Exception.hpp:46
const char * nvSciGetErrorName(uint32_t error)
~Exception() noexcept override=default