jexcept.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifndef __JEXCEPT__
  14. #define __JEXCEPT__
  15. #include "jiface.hpp"
  16. #include "jlib.hpp"
  17. #include "errno.h"
  18. jlib_decl const char* serializeMessageAudience(MessageAudience ma);
  19. jlib_decl MessageAudience deserializeMessageAudience(const char* text);
  20. //the following interface to be thrown when a user command explicitly calls for a failure
  21. interface jlib_thrown_decl IUserException : public IException
  22. {
  23. };
  24. //the following interface defines a collection of exceptions
  25. //
  26. interface jlib_thrown_decl IMultiException : extends IException
  27. {
  28. //convenience methods for handling this as an array
  29. virtual aindex_t ordinality() const = 0;
  30. virtual IException& item(aindex_t pos) const = 0;
  31. virtual const char* source() const = 0;
  32. //for complete control...
  33. virtual IArrayOf<IException>& getArray()= 0;
  34. //add another exception
  35. virtual void append(IException& e) = 0;
  36. virtual void append(IMultiException& e) = 0;
  37. virtual StringBuffer& serialize(StringBuffer& ret, unsigned indent = 0, bool simplified=false, bool root=true) const = 0;
  38. virtual StringBuffer& serializeJSON(StringBuffer& ret, unsigned indent = 0, bool simplified=false, bool root=true, bool enclose=false) const = 0;
  39. virtual void deserialize(const char* xml) = 0; //throws IException on failure!
  40. //the following methods override those in IIException
  41. //
  42. virtual int errorCode() const = 0;
  43. virtual StringBuffer& errorMessage(StringBuffer &msg) const = 0;
  44. virtual MessageAudience errorAudience() const = 0;
  45. };
  46. IMultiException jlib_decl *makeMultiException(const char* source = NULL);
  47. interface IExceptionHandler
  48. {
  49. virtual bool fireException(IException *e) = 0;
  50. };
  51. IException jlib_decl *makeStringExceptionV(int code, const char *why, ...) __attribute__((format(printf, 2, 3)));
  52. IException jlib_decl *makeStringExceptionVA(int code, const char *why, va_list args) __attribute__((format(printf, 2, 0)));
  53. IException jlib_decl *makeStringException(int code, const char *why);
  54. IException jlib_decl *makeStringExceptionV(MessageAudience aud, int code, const char *why, ...) __attribute__((format(printf, 3, 4)));
  55. IException jlib_decl *makeStringExceptionVA(MessageAudience aud, int code, const char *why, va_list args) __attribute__((format(printf, 3, 0)));
  56. IException jlib_decl *makeStringException(MessageAudience aud, int code, const char *why);
  57. __declspec(noreturn) void jlib_decl throwStringExceptionV(int code, const char *format, ...) __attribute__((format(printf, 2, 3), noreturn));
  58. IException jlib_decl *makeWrappedExceptionVA(IException *e, int code, const char *why, va_list args) __attribute__((format(printf, 3, 0)));
  59. IException jlib_decl *makeWrappedExceptionV(IException *e, int code, const char *why, ...) __attribute__((format(printf, 3, 4)));
  60. // Macros for legacy names of above functions
  61. #define MakeMultiException makeMultiException
  62. #define MakeStringException makeStringExceptionV
  63. #define MakeStringExceptionVA makeStringExceptionVA
  64. #define MakeStringExceptionDirect makeStringException
  65. #define ThrowStringException throwStringExceptionV
  66. interface jlib_thrown_decl IOSException: extends IException{};
  67. IOSException jlib_decl *makeOsException(int code);
  68. IOSException jlib_decl *makeOsException(int code, const char *msg);
  69. IOSException jlib_decl *makeOsExceptionV(int code, const char *msg, ...) __attribute__((format(printf, 2, 3)));
  70. #define DISK_FULL_EXCEPTION_CODE ENOSPC
  71. interface jlib_thrown_decl IErrnoException: extends IException{};
  72. IErrnoException jlib_decl *makeErrnoException(int errn, const char *why);
  73. IErrnoException jlib_decl *makeErrnoException(const char *why);
  74. IErrnoException jlib_decl *makeErrnoExceptionV(int errn, const char *why, ...) __attribute__((format(printf, 2, 3)));
  75. IErrnoException jlib_decl *makeErrnoExceptionV(const char *why, ...) __attribute__((format(printf, 1, 2)));
  76. IErrnoException jlib_decl *makeErrnoException(MessageAudience aud, int errn, const char *why);
  77. IErrnoException jlib_decl *makeErrnoExceptionV(MessageAudience aud, int errn, const char *why, ...) __attribute__((format(printf, 3, 4)));
  78. IErrnoException jlib_decl *makeErrnoExceptionV(MessageAudience aud, const char *why, ...) __attribute__((format(printf, 2, 3)));
  79. void jlib_decl pexception(const char *msg,IException *e); // like perror except for exceptions
  80. jlib_decl StringBuffer & formatSystemError(StringBuffer & out, unsigned errcode);
  81. void userBreakpoint();
  82. interface jlib_thrown_decl ISEH_Exception : extends IException
  83. {
  84. };
  85. interface jlib_thrown_decl IOutOfMemException: extends IException
  86. {
  87. };
  88. void jlib_decl enableSEHtoExceptionMapping();
  89. void jlib_decl disableSEHtoExceptionMapping();
  90. // NB only enables for current thread or threads started after call
  91. // requires /EHa option to be set in VC++ options (after /GX)
  92. // Macros for legacy names of above functions
  93. #define EnableSEHtoExceptionMapping enableSEHtoExceptionMapping
  94. #define DisableSEHtoExceptionMapping disableSEHtoExceptionMapping
  95. void jlib_decl *setSEHtoExceptionHandler(IExceptionHandler *handler); // sets handler and return old value
  96. void jlib_decl setTerminateOnSEHInSystemDLLs(bool set=true);
  97. void jlib_decl setTerminateOnSEH(bool set=true);
  98. __declspec(noreturn) void jlib_decl throwUnexpectedException(const char * file, unsigned line) __attribute__((noreturn));
  99. __declspec(noreturn) void jlib_decl throwUnexpectedException(const char * where, const char * file, unsigned line) __attribute__((noreturn));
  100. const char jlib_decl *sanitizeSourceFile(const char *file);
  101. #define makeUnexpectedException() makeStringExceptionV(9999, "Internal Error at %s(%d)", sanitizeSourceFile(__FILE__), __LINE__)
  102. #define throwUnexpected() throwUnexpectedException(sanitizeSourceFile(__FILE__), __LINE__)
  103. #define throwUnexpectedX(x) throwUnexpectedException(x, sanitizeSourceFile(__FILE__), __LINE__)
  104. #define assertThrow(x) assertex(x)
  105. #define UNIMPLEMENTED throw makeStringExceptionV(-1, "UNIMPLEMENTED feature at %s(%d)", sanitizeSourceFile(__FILE__), __LINE__)
  106. #define UNIMPLEMENTED_X(reason) throw makeStringExceptionV(-1, "UNIMPLEMENTED '" reason "' at %s(%d)", sanitizeSourceFile(__FILE__), __LINE__)
  107. #define UNIMPLEMENTED_XY(a,b) throw makeStringExceptionV(-1, "UNIMPLEMENTED " a " %s at %s(%d)", b, sanitizeSourceFile(__FILE__), __LINE__)
  108. IException jlib_decl * deserializeException(MemoryBuffer & in);
  109. void jlib_decl serializeException(IException * e, MemoryBuffer & out);
  110. void jlib_decl printStackReport(__int64 startIP = 0);
  111. // Macro for legacy name of above function
  112. #define PrintStackReport printStackReport
  113. bool jlib_decl getAllStacks(StringBuffer &output);
  114. #ifdef _DEBUG
  115. #define RELEASE_CATCH_ALL int*********
  116. #else
  117. #define RELEASE_CATCH_ALL ...
  118. #endif
  119. //These are used in several places to wrap error reporting, to keep error numbers+text together. E.g.,
  120. //#define XYZfail 99 #define XXZfail_Text "Failed" throwError(XYZfail)
  121. #define throwError(x) throwStringExceptionV(x, (x ## _Text))
  122. #define throwError1(x,a) throwStringExceptionV(x, (x ## _Text), a)
  123. #define throwError2(x,a,b) throwStringExceptionV(x, (x ## _Text), a, b)
  124. #define throwError3(x,a,b,c) throwStringExceptionV(x, (x ## _Text), a, b, c)
  125. #define throwError4(x,a,b,c,d) throwStringExceptionV(x, (x ## _Text), a, b, c, d)
  126. //---------------------------------------------------------------------------------------------------------------------
  127. //These values are persisted - so should not be reordered.
  128. enum ErrorSeverity
  129. {
  130. SeverityInformation = 0,
  131. SeverityWarning = 1,
  132. SeverityError = 2,
  133. SeverityAlert = 3,
  134. SeverityIgnore = 4,
  135. SeverityFatal = 5, // a fatal error - can't be mapped to anything else
  136. SeverityUnknown,
  137. SeverityMax = SeverityUnknown
  138. };
  139. inline bool isError(ErrorSeverity severity) { return severity == SeverityError || severity == SeverityFatal; }
  140. inline bool isFatal(ErrorSeverity severity) { return severity == SeverityFatal; }
  141. //TBD in a separate commit - add support for warnings to be associated with different categories
  142. enum WarnErrorCategory
  143. {
  144. CategoryInformation,// Some kind of information [default severity information]
  145. CategoryCast, // Suspicious casts between types or out of range values
  146. CategoryConfuse, // Likely to cause confusion
  147. CategoryDeprecated, // deprecated features or syntax
  148. CategoryEfficiency, // Something that is likely to be inefficient
  149. CategoryFolding, // Unusual results from constant folding
  150. CategoryFuture, // Likely to cause problems in future versions
  151. CategoryIgnored, // Something that has no effect, or is ignored
  152. CategoryIndex, // Unusual indexing of datasets or strings
  153. CategoryMistake, // Almost certainly a mistake
  154. CategoryLimit, // An operation that should really have some limits to protect data runaway
  155. CategorySyntax, // Invalid syntax which is painless to recover from
  156. CategoryUnusual, // Not strictly speaking an error, but highly unusual and likely to be a mistake
  157. CategoryUnexpected, // Code that could be correct, but has the potential for unexpected behaviour
  158. CategoryCpp, // Warning passed through from C++ compiler
  159. CategorySecurity, // Security warnings - operations that will be refused at codegen time unless unused.
  160. CategoryDFS, // DFS resolution issues - field translation may not have occurred even though requested
  161. CategoryError, // Typically severity fatal
  162. CategoryAll,
  163. CategoryUnknown,
  164. CategoryMax,
  165. };
  166. interface jlib_thrown_decl IError : public IException
  167. {
  168. public:
  169. virtual const char* getFilename() const = 0;
  170. virtual WarnErrorCategory getCategory() const = 0;
  171. virtual int getLine() const = 0;
  172. virtual int getColumn() const = 0;
  173. virtual int getPosition() const = 0;
  174. virtual StringBuffer& toString(StringBuffer&) const = 0;
  175. virtual ErrorSeverity getSeverity() const = 0;
  176. virtual IError * cloneSetSeverity(ErrorSeverity _severity) const = 0;
  177. virtual unsigned getActivity() const = 0;
  178. virtual const char * queryScope() const = 0;
  179. virtual IPropertyTree * toTree() const = 0;
  180. };
  181. interface IWorkUnit;
  182. interface jlib_decl IErrorReceiver : public IInterface
  183. {
  184. virtual void report(IError* error) = 0;
  185. virtual IError * mapError(IError * error) = 0;
  186. virtual size32_t errCount() = 0;
  187. virtual size32_t warnCount() = 0;
  188. virtual void exportMappings(IWorkUnit * wu) const = 0;
  189. virtual __declspec(noreturn) void ThrowStringException(int code,const char *format, ...) const __attribute__((format(printf, 3, 4), noreturn)); // override the global function to try and add more context information
  190. //global helper functions
  191. void reportError(int errNo, const char *msg, const char *filename, int lineno, int column, int pos);
  192. void reportWarning(WarnErrorCategory category, int warnNo, const char *msg, const char *filename, int lineno, int column, int pos);
  193. };
  194. inline bool isError(IError * error) { return isError(error->getSeverity()); }
  195. inline bool isFatal(IError * error) { return isFatal(error->getSeverity()); }
  196. extern jlib_decl ErrorSeverity queryDefaultSeverity(WarnErrorCategory category);
  197. extern jlib_decl IError *createError(WarnErrorCategory category, ErrorSeverity severity, int errNo, const char *msg, const char *filename, int lineno=0, int column=0, int pos=0, unsigned activity = 0, const char * scope = nullptr);
  198. extern jlib_decl IError *createError(WarnErrorCategory category, ErrorSeverity severity, int errNo, const char *msg, unsigned activity, const char * scope);
  199. extern jlib_decl IError *createError(IPropertyTree * tree);
  200. inline IError * createError(int errNo, const char *msg, const char *filename, int lineno=0, int column=0, int pos=0)
  201. {
  202. return createError(CategoryError, SeverityFatal, errNo, msg, filename, lineno, column, pos);
  203. }
  204. #endif