libsex
3.1.0
simple exception library (C++)
|
00001 /** 00002 * @file 00003 * 00004 * Declaration of @ref libsex::Exception. 00005 */ 00006 00007 /** 00008 * @mainpage Example 00009 * 00010 * The unit tests serve as compilable and runnable 00011 * documentation (not included in this API documentation). 00012 * 00013 * @n@n 00014 * 00015 * At first, let's declare a very primitive exception in 00016 * @c tests/framework/ExampleException1.hxx 00017 * @include framework/ExampleException1.hxx 00018 * 00019 * We then define it and assign an error message in 00020 * @c tests/framework/ExampleException1.cxx 00021 * @include framework/ExampleException1.cxx 00022 * 00023 * We repeat that procedure to create a more sophisticated 00024 * class: 00025 * 00026 * @c tests/framework/ExampleException2.hxx 00027 * @include framework/ExampleException2.hxx 00028 * 00029 * @c tests/framework/ExampleException2.cxx 00030 * @include framework/ExampleException2.cxx 00031 * 00032 * Finally, here's how to use those classes and the 00033 * framework: 00034 * 00035 * @c tests/UsageExamples.cxx 00036 * @include UsageExamples.cxx 00037 */ 00038 00039 #ifndef LIBSEX_EXCEPTION_HXX 00040 #define LIBSEX_EXCEPTION_HXX 00041 00042 #include <exception> // std::exception 00043 #include <stdexcept> // std::bad_alloc 00044 #include <ostream> // std::ostream 00045 00046 namespace libsex 00047 { 00048 class Exception; 00049 } 00050 00051 /** 00052 * @class libsex::Exception 00053 * 00054 * Generic error made up of a message and 00055 * (optional) references to previous one. 00056 * 00057 * Double-fault save (not throwing std::bad_alloc 00058 * or other exceptions in critical situations) and 00059 * allows exception chaining. 00060 * 00061 * For object-oriented error handling you should 00062 * subclass this class for every type of error. 00063 * There are elegant macros in @file declare.hxx 00064 * and @file define.hxx. 00065 */ 00066 class libsex::Exception : public std::exception 00067 { 00068 public: 00069 /// Max payload of the internal character string. 00070 static const unsigned short LENGTH = 500; 00071 00072 /** 00073 * Creates an exception. 00074 * 00075 * Supplied character array should be null- 00076 * terminated and should not exceed LENGTH 00077 * characters (excl. null byte). Its contents will 00078 * be copied into an internal buffer and can be 00079 * overwritten/freed afterwards. 00080 * 00081 * The constructors do not accept std::string 00082 * since that class uses the heap and may throw 00083 * std::bad_alloc -- which might obviously happen 00084 * even before this constructor is entered and 00085 * thus might result in loss of the actual (chain 00086 * of) exception(s) describing the error. 00087 */ 00088 Exception(const char* const message) throw(); 00089 00090 /** 00091 * Creates a chained exception. 00092 * 00093 * Both the error message and the previous 00094 * exception are cloned. 00095 * 00096 * Since exceptions should be created on the stack 00097 * (see std::bad_alloc), the previous one will be 00098 * internally copied to the heap by calling 00099 * clone(). 00100 * 00101 * If clone() throws std::bad_alloc, a notice is 00102 * appended to the internal message buffer of this 00103 * exception (as long as space left) and 00104 * std::bad_alloc is swallowed. 00105 * 00106 * @see Exception(message) 00107 */ 00108 Exception( 00109 const char* const message, 00110 const Exception& previous) throw(); 00111 00112 /// No-op. 00113 virtual ~Exception() throw(); 00114 00115 /** 00116 * Writes our message to passed stream. 00117 * 00118 * @exception std::ios_base::failure 00119 * may be thrown by stream, if it is 00120 * configured to do so. 00121 */ 00122 void write(std::ostream& out) const throw(std::ios_base::failure); 00123 00124 /** 00125 * Writes a backtrace to passed stream. 00126 * 00127 * Messages are delimited by one newline and are 00128 * printed in reverse chronological order. 00129 * 00130 * @exception std::ios_base::failure 00131 * may be thrown by stream, if it is 00132 * configured to do so. 00133 */ 00134 void backtrace(std::ostream& out) const throw(std::ios_base::failure); 00135 00136 /** 00137 * Creates a shallow copy of this exception. 00138 * 00139 * Copy is allocated on the heap. 00140 * 00141 * @throws std::bad_alloc on memory shortage. 00142 */ 00143 virtual const Exception* clone() const throw(std::bad_alloc); 00144 00145 /// Returns a pointer to the internal character string. 00146 virtual const char* what() const throw(); 00147 00148 private: 00149 /** 00150 * Copy of message passed to constructor. 00151 * 00152 * Length is @ref Exception::LENGTH plus nullbyte. 00153 */ 00154 char _message[LENGTH + 1]; 00155 00156 /// Pointer to copy of previous exception, or null. 00157 const Exception* _previous; 00158 00159 /// Used by constructors to initialize _message. 00160 void _initMessage(const char* const message); 00161 }; 00162 00163 #endif