1 #ifndef LIBSEX_EXCEPTION_HXX
2 #define LIBSEX_EXCEPTION_HXX
4 #include <exception> // std::exception
5 #include <stdexcept> // std::bad_alloc
6 #include <ostream> // std::ostream
11 * Resembles a generic error, stores a message and
12 * optionally references one previous error (linked list).
14 * The supplied character array must be terminated by a
15 * nullbyte. It will be copied into an internal array
16 * (stored on the stack) that is @ref LENGTH chars long,
17 * until the nullbyte is reached or the internal array is
20 * It is possible create chained exceptions. Since we have
21 * to assume that all exceptions are created on the stack,
22 * the previous exception will be copied to the heap and
23 * the current exception stores a pointer to this copy
24 * (singly linked list).
26 * Hence, it is possible that, while having a chain of
27 * exceptions "bubbling up", a std::bad_alloc is thrown. In
28 * this case, a notice is appended and both std::bad_alloc
29 * and previous exceptions are ignored.
31 * @note For OO error handling you should subclass this
32 * class for every type of error. Inheriting by hand
33 * is tedious, you usally don't want to do this.
34 * There are some efficient macros in @file
37 class Exception
: public std::exception
40 /// Max payload of the internal character string.
41 static const unsigned short LENGTH
= 500;
44 * Creates an exception.
46 * The specified message is copied into an internal
47 * buffer of @ref LENGTH + 1 (nullbyte) characters
50 Exception(const char* const message
) throw();
53 * Creates a chained exception.
55 * Both the error message and the previous
56 * exception are copied. While @a message is copied
57 * into an internal buffer, clone() is send to @a
58 * previous which in turn dynamically creates a
59 * shallow copy of itsself on the heap and returns
62 * Hence, it is possible that clone() may throw
63 * std::bad_alloc. In that case, a notice is
64 * appended to this message (as long as the
65 * internal buffer contains free fields) and the
66 * instance of std::bad_alloc is swallowed.
69 const char* const message
,
70 const Exception
& previous
) throw();
73 virtual ~Exception() throw();
76 * Writes our message to passed stream.
78 * @exception std::ios_base::failure
79 * may be thrown by stream, if it is
80 * configured to do so.
82 void write(std::ostream
& out
) const throw(std::ios_base::failure
);
85 * Writes a backtrace to passed stream.
87 * Messages are delimited by one newline and are
88 * printed in reverse chronological order.
90 * @exception std::ios_base::failure
91 * may be thrown by stream, if it is
92 * configured to do so.
94 void backtrace(std::ostream
& out
) const throw(std::ios_base::failure
);
97 * Clones this exception.
98 * @throws std::bad_alloc on memory shortage.
100 virtual const Exception
* clone() const throw(std::bad_alloc
);
102 /// Returns a pointer to the internal character string.
103 virtual const char* what() const throw();
107 * Copy of message passed to constructor.
109 * Length is @ref Exception::LENGTH plus nullbyte.
111 char _message
[LENGTH
+ 1];
113 /// Pointer to copy of previous exception, or null.
114 const Exception
* _previous
;
116 /// Used by constructors to initialize _message.
117 void _initMessage(const char* const message
);