ctkException.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*=============================================================================
  2. Library: CTK
  3. Copyright (c) German Cancer Research Center,
  4. Division of Medical and Biological Informatics
  5. Licensed under the Apache License, Version 2.0 (the "License");
  6. you may not use this file except in compliance with the License.
  7. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. =============================================================================*/
  15. #ifndef __ctkException_h
  16. #define __ctkException_h
  17. // Qt includes
  18. #include <QString>
  19. #include <QSet>
  20. // CTK includes
  21. #include <ctkCoreExport.h>
  22. #include <ctkBackTrace.h>
  23. //---------------------------------------------------------------------------
  24. /**
  25. * \ingroup Core
  26. *
  27. * \brief The base class for all exceptions defined in CTK.
  28. *
  29. * This exception class takes a QString object as the message text and can
  30. * optionally store another ctkException instance which caused this exception.
  31. *
  32. * ctkException classes can be copied, saved, and rethrown.
  33. */
  34. class CTK_CORE_EXPORT ctkException : public std::exception, public ctkBackTrace
  35. {
  36. public:
  37. class TraceManipulator
  38. {
  39. public:
  40. TraceManipulator(const ctkException* e);
  41. QDebug print(QDebug dbg) const;
  42. private:
  43. const ctkException* Exc;
  44. };
  45. /**
  46. * @brief Create a new ctkException.
  47. * @param msg The exception message.
  48. */
  49. explicit ctkException(const QString& msg);
  50. /**
  51. * @brief Create a new ctkException containing another exception as the cause.
  52. * @param msg The exception message.
  53. * @param cause The nested exception causing this exception.
  54. */
  55. ctkException(const QString& msg, const ctkException& cause);
  56. /**
  57. * @brief Copy constructor.
  58. * @param o The exception to copy.
  59. */
  60. ctkException(const ctkException& o);
  61. /**
  62. * @brief Assignment operator.
  63. * @param o The exception to assign to this exception.
  64. * @return
  65. */
  66. ctkException& operator=(const ctkException& o);
  67. ~ctkException() throw();
  68. /**
  69. * @brief Gets the nested exception which caused this exception.
  70. * @return The nested exception, or <code>NULL</code> if there is none.
  71. */
  72. const ctkException* cause() const throw();
  73. /**
  74. * @brief Sets the cause for this exception.
  75. * @param cause The exception causing this exception.
  76. */
  77. void setCause(const ctkException& cause);
  78. /**
  79. * @brief Returns the name for this exception.
  80. * @return The exception name.
  81. */
  82. virtual const char* name() const throw();
  83. /**
  84. * @brief Returns the class name for this exception.
  85. * @return The exception class name.
  86. */
  87. virtual const char* className() const throw();
  88. /**
  89. * @brief Returns a static string describing this exception.
  90. * @return The exception description.
  91. */
  92. virtual const char* what() const throw();
  93. /**
  94. * @brief Returns the detail message string of this exception.
  95. * @return The detail exception message.
  96. */
  97. QString message() const throw();
  98. /**
  99. * @brief Returns an object suitable for printing this executable
  100. * and its backtrace via qDebug().
  101. *
  102. * Example usage:
  103. * \code
  104. * ctkException exc("My error");
  105. * qDebug() << exc.printStackTrace();
  106. * \endcode
  107. *
  108. * @return A helper object for streaming to qDebug().
  109. */
  110. TraceManipulator printStackTrace() const;
  111. /**
  112. * @brief Creates a copy of this exception. Use rethrow() to throw the
  113. * copy again.
  114. * @return A copy of this exception.
  115. */
  116. virtual ctkException* clone() const;
  117. /**
  118. * @brief (Re)Throws this exception.
  119. */
  120. virtual void rethrow() const;
  121. protected:
  122. friend class TraceManipulator;
  123. /**
  124. * @brief Print the stack trace of this exception using the given QDebug object.
  125. * @param dbg
  126. * @return
  127. */
  128. virtual QDebug printStackTrace(QDebug dbg) const;
  129. private:
  130. QString Msg;
  131. mutable std::string WhatMsg;
  132. ctkException* NestedException;
  133. void printEnclosedStackTrace(QDebug dbg, const QList<QString>& enclosingTrace,
  134. const QString& caption, const QString& prefix,
  135. QSet<const ctkException*>& dejaVu);
  136. };
  137. //---------------------------------------------------------------------------
  138. /**
  139. * \ingroup Core
  140. */
  141. CTK_CORE_EXPORT QDebug operator<<(QDebug dbg, const ctkException& exc);
  142. //---------------------------------------------------------------------------
  143. /**
  144. * \ingroup Core
  145. */
  146. CTK_CORE_EXPORT QDebug operator<<(QDebug dbg, const ctkException::TraceManipulator& trace);
  147. //---------------------------------------------------------------------------
  148. /**
  149. * \ingroup Core
  150. *
  151. * \brief Quickly declare a ctkException sub-class.
  152. * \param API The export macro.
  153. * \param CLS The class name for the ctkException sub-class.
  154. * \param BASE The class name of the actual super class.
  155. */
  156. #define CTK_DECLARE_EXCEPTION(API, CLS, BASE) \
  157. class API CLS : public BASE \
  158. { \
  159. public: \
  160. explicit CLS(const QString& msg); \
  161. CLS(const QString& msg, const ctkException& exc); \
  162. CLS(const CLS& exc); \
  163. ~CLS() throw(); \
  164. CLS& operator = (const CLS& exc); \
  165. const char* name() const throw(); \
  166. CLS* clone() const; \
  167. void rethrow() const ; \
  168. };
  169. //---------------------------------------------------------------------------
  170. /**
  171. * \ingroup Core
  172. *
  173. * \brief Quickly implement a ctkException sub-class
  174. * \param CLS The class name for the ctkException sub-class.
  175. * \param BASE The class name of the actual super class.
  176. * \param NAME A human-readable name for this exception class.
  177. */
  178. #define CTK_IMPLEMENT_EXCEPTION(CLS, BASE, NAME) \
  179. CLS::CLS(const QString& msg) : BASE(msg) \
  180. { } \
  181. CLS::CLS(const QString& msg, const ctkException& exc) : BASE(msg, exc) \
  182. { } \
  183. CLS::CLS(const CLS& exc) : BASE(exc) \
  184. { } \
  185. CLS::~CLS() throw() \
  186. { } \
  187. CLS& CLS::operator = (const CLS& exc) \
  188. { \
  189. BASE::operator = (exc); \
  190. return *this; \
  191. } \
  192. const char* CLS::name() const throw() \
  193. { \
  194. return NAME; \
  195. } \
  196. CLS* CLS::clone() const \
  197. { \
  198. return new CLS(*this); \
  199. } \
  200. void CLS::rethrow() const \
  201. { \
  202. throw *this; \
  203. }
  204. CTK_DECLARE_EXCEPTION(CTK_CORE_EXPORT, ctkUnsupportedOperationException, ctkException)
  205. CTK_DECLARE_EXCEPTION(CTK_CORE_EXPORT, ctkRuntimeException, ctkException)
  206. CTK_DECLARE_EXCEPTION(CTK_CORE_EXPORT, ctkInvalidArgumentException, ctkRuntimeException)
  207. CTK_DECLARE_EXCEPTION(CTK_CORE_EXPORT, ctkIllegalStateException, ctkRuntimeException)
  208. #endif // __ctkException_h