Streaming C++ API
Exceptions.hpp
1//
2// Copyright (c) 2004-2023 TIBCO Software Inc. All rights reserved.
3//
4
5#ifndef STREAMBASE_EXCEPTIONS_H
6#define STREAMBASE_EXCEPTIONS_H
7
8#include "StreamBase.hpp"
9#include <string>
10#include <exception>
11#include <vector>
12#include <streambase/impl/Memory.hpp>
13#include "Errors.hpp"
14
15// For NMSTL_ASSERT_UNREACHABLE
16#include <NMSTL/internal.hpp>
17
18SB_INTERNAL_FWD(XMLExceptionBuilder);
19SB_INTERNAL_FWD(Errors);
20SB_INTERNAL_FWD(StackTrace);
21
22SB_NAMESPACE_BEGIN;
23
24#include "ExceptionCodes.hpp"
25
26#define SB_Throw(x) do { \
27 x.file(__FILE__).line(__LINE__).function(__FUNCTION__).throwMyself(); \
28 NMSTL_ASSERT_UNREACHABLE(); \
29} while(0)
30
31// ________________________________________________________________________
32/// The base class for all StreamBaseExceptions. Currently defined exceptions
33/// include
34///
35/// - StreamBaseNoSuchEntityException: requested an entity which doesn't exist
36/// - StreamBaseBadXmlException: non-well-formed (i.e., unparseable) XML
37/// - StreamBaseBadEntityException: semantically invalid entity description (e.g., box doesn't have a type)
38/// - StreamBaseTypingException: typechecking failed
39/// - StreamBaseIllegalArgumentException: miscellaneous illegal argument provided
40///
41/// An StreamBaseException should never be thrown directly; use the
42/// Throw macro instead.
43class StreamBaseException : public std::exception {
44 public:
45 /// Constructor.
46 ///
47 /// @param code see ExceptionsCodes.hpp; use SB_NEW_MESSAGE_CODE if in doubt
48 /// @param message the exception message
49 /// @param error_type the class of error, for server runtime error handling
50 /// @param type the type of the exception
51 StreamBaseException(std::string code, std::string message,
52 sb_internal::Errors::Type error_type = sb_internal::Errors::UNKNOWNTYPE,
53 std::string type = "StreamBaseException");
54
55 /// Constructor.
56 ///
57 /// @param code see ExceptionsCodes.hpp; use SB_NEW_MESSAGE_CODE if in doubt
58 /// @param message the exception message
59 /// @param c an exception that is the "cause" of this exception
60 /// @param error_type the class of error, for server runtime error handling
61 /// @param type the type of the exception
62 StreamBaseException(std::string code, std::string message, StreamBaseException& c,
63 sb_internal::Errors::Type error_type = sb_internal::Errors::UNKNOWNTYPE,
64 std::string type = "StreamBaseException");
65
66#ifndef DOXYGEN_SKIP
67 /// Create a StreamBaseException from a given xmlstring. Xmlstring must start with
68 /// the <exception> node as produced by asXmlString
69 static StreamBaseException fromXmlString(const std::string &xmlstring, std::shared_ptr<StreamBaseException> cause = std::shared_ptr<StreamBaseException>());
70#endif
71
72 /// Destructor.
73 virtual ~StreamBaseException() throw();
74
75 /// Returns the message as a C string. The string is owned by this
76 /// object, so the pointer becomes invalid upon destruction of the
77 /// StreamBaseException.
78 virtual const char *what() const throw() { return _message.c_str(); }
79
80#ifndef DOXYGEN_SKIP
81 /// Returns the message.
82 std::string getMessage() const { return _message; }
83 std::string getSummary() const { return _summary.empty() ? _message : _summary; }
84
85 /// Returns the source file line number, function in which the exception was
86 /// thrown (or an empty string if unknown).
87 std::string getFile() const { return _file; }
88 unsigned int getLine() const { return _line; }
89 std::string getFunction() const { return _function; }
90
91 /// Returns the type of the exception (e.g., "StreamBaseException" or
92 /// "StreamBaseNoSuchEntityException").
93 std::string getType() const { return _type; }
94
95 /// Returns the Errors::Type of the exception FATAL, NON_FATAL, MEM, etc..
96 ///
97 sb_internal::Errors::Type getErrorType() const { return _error_type; }
98
99 /// Returns a description containing all known information about the message.
100 std::string as_string() const;
101
102 /// Returns a stack trace describing where the exception was
103 /// thrown. Uses external programs; may be very slow.
104 std::string getStackTrace() const;
105
106 // Find exception in chain that matches type. Return NULL
107 StreamBaseException *findByType(const std::string type);
108 // Return deepest exception in chain
109 StreamBaseException& getDeepest();
110
111 // Return exception chain as a string, for various contexts
112 virtual std::string asXmlStringSingle() const;
113 virtual std::string asXmlString() const; // return chain as XML tree, for wire
114 virtual std::string chainAsString() const; // return chain, as printable string
115 virtual std::string linkAsString() const; // return single link of chain, as string
116 virtual std::string getChainOfMessages() const; // chain all exception messages together
117
118 std::string getCode() const { return _code; }
119 StreamBaseException& getCause() const { return *_cause; }
120 bool hasCause() const { return _cause.get() != NULL; } // does this exception have a cause?
121
122 const std::string getParam(const std::string name) const;
123 // some convenience param getters
124 const std::string getBoxParam() const;
125 const std::string getBoxName() const;
126 const std::string getFieldName() const;
127
128 StreamBaseException& param(const std::string name, const std::string val);
129 StreamBaseException& param(const std::string name, int val);
130 StreamBaseException& code(std::string val);
131 StreamBaseException& code(int val);
132 StreamBaseException& file(const char *val);
133 StreamBaseException& file(std::string val);
134 StreamBaseException& line(int val);
135 StreamBaseException& function(const char *val);
136 StreamBaseException& function(std::string val);
137 StreamBaseException& type(std::string val);
138 StreamBaseException& message(std::string val);
139 StreamBaseException& cause(const StreamBaseException& val);
140
141 StreamBaseException& summary(std::string val);
142
143 // some convenience param setters
144 StreamBaseException& boxparam(std::string name);
145 StreamBaseException& boxname(std::string name);
146 StreamBaseException& fieldname(std::string name);
147
148 virtual void throwMyself();
149#endif
150
151 protected:
152 virtual std::string causeAsXmlString() const; // create an xmlstring for the cause
153 private:
154 struct StackTraceHolder {
155 std::shared_ptr<sb_internal::StackTrace> _trace;
156 StackTraceHolder(const std::shared_ptr<sb_internal::StackTrace>&);
157 StackTraceHolder(const StackTraceHolder&);
158 StackTraceHolder& operator = (const StackTraceHolder&);
159 ~StackTraceHolder();
160 };
161
162 std::string _message;
163 std::string _file;
164 unsigned int _line;
165 std::string _function;
166 std::string _type;
167 StackTraceHolder _trace;
168 sb_internal::Errors::Type _error_type;
169 std::map<std::string,std::string> _params;
170 std::string _code;
171 std::string _summary;
172 std::shared_ptr <StreamBaseException> _cause;
173 std::string _xmlNodeLocation;
174 friend class sb_internal::XMLExceptionBuilder;
175};
176
177#ifdef DOXYGEN_SKIP
178#define STREAMBASE_EXCEPTION_SUBTYPE(cl, parent, error_type) class cl : public parent {};
179#else
180
181#define STREAMBASE_EXCEPTION_SUBTYPE(cl, parent, error_type) \
182class cl : public parent { \
183 public: \
184 cl(std::string code, std::string message, sb_internal::Errors::Type a_error_type=error_type, const char *type=#cl) : \
185 parent(code, message, a_error_type, type ? type : #cl) {} \
186 cl(std::string code, std::string message, StreamBaseException& c, sb_internal::Errors::Type a_error_type=error_type, const char *type=#cl) : \
187 parent(code, message, c, a_error_type, type ? type : #cl) {} \
188 void throwMyself() { throw(*this); }; \
189}
190
191#endif // DOXYGEN_SKIP
192
193#define STREAMBASE_EXCEPTION_TYPE(cl, error_type) \
194 STREAMBASE_EXCEPTION_SUBTYPE(cl, StreamBaseException, error_type)
195
196
197/// Requested an entity which doesn't exist.
198STREAMBASE_EXCEPTION_TYPE(StreamBaseNoSuchEntityException, sb_internal::Errors::NON_FATAL_ERROR);
199
200/// Non-well-formed XML.
201STREAMBASE_EXCEPTION_TYPE(StreamBaseBadXmlException, sb_internal::Errors::XML_ERROR);
202
203/// Semantically invalid XML (e.g., box doesn't have a type).
204STREAMBASE_EXCEPTION_TYPE(StreamBaseBadEntityException, sb_internal::Errors::NON_FATAL_ERROR);
205
206/// Typechecking failed.
207STREAMBASE_EXCEPTION_TYPE(StreamBaseTypingException, sb_internal::Errors::TYPECHECK_ERROR);
208
209/// Miscellaneous illegal argument.
210STREAMBASE_EXCEPTION_TYPE(StreamBaseIllegalArgumentException, sb_internal::Errors::XMLRPC_ERROR);
211
212/// A feature is not implemented.
213STREAMBASE_EXCEPTION_TYPE(StreamBaseNotImplementedException, sb_internal::Errors::NON_FATAL_ERROR);
214
215/// A feature is not supported.
216STREAMBASE_EXCEPTION_TYPE(StreamBaseNotSupportedException, sb_internal::Errors::NON_FATAL_ERROR);
217
218/// A network (TCP/IP) error was encountered.
219STREAMBASE_EXCEPTION_TYPE(StreamBaseNetworkException, sb_internal::Errors::XMLRPC_ERROR);
220
221/// A network timeout error was encountered.
222STREAMBASE_EXCEPTION_TYPE(StreamBaseTimeoutException, sb_internal::Errors::NETWORK_ERROR);
223
224/// A dequeued result was not available in the time allowed
225STREAMBASE_EXCEPTION_TYPE(StreamBaseDequeueTimeoutException, sb_internal::Errors::NETWORK_ERROR);
226
227/// Illegal Argument
228STREAMBASE_EXCEPTION_TYPE(IllegalArgumentException, sb_internal::Errors::NON_FATAL_ERROR);
229
230/// Null value encountered
231STREAMBASE_EXCEPTION_TYPE(NullValueException, sb_internal::Errors::NON_FATAL_ERROR);
232
233/// An XML/RPC error has occurred.
235 public:
236 StreamBaseXmlRpcFault(int fault_code, std::string fault_string);
237 StreamBaseXmlRpcFault(std::string code, std::string message,
238 sb_internal::Errors::Type error_type = sb_internal::Errors::UNKNOWNTYPE,
239 std::string type = "StreamBaseXmlRpcFault");
240
241 StreamBaseXmlRpcFault(std::string code, std::string message, StreamBaseException& c,
242 sb_internal::Errors::Type error_type = sb_internal::Errors::UNKNOWNTYPE,
243 std::string type = "StreamBaseXmlRpcFault");
244
245#ifndef DOXYGEN_SKIP
246 //const StreamBaseXmlRpcFault& throwMyself() { throw(*this); return *this; }
247 void throwMyself() { throw(*this); }
248#endif
249};
250
251/// An Exception which contains a list of cause exceptions
253 private:
254 std::vector<StreamBaseException> causes;
255 protected:
256 virtual std::string causeAsXmlString() const; // create an xmlstring for the cause
257 public:
258 StreamBaseListException(std::string code, std::string message, const std::vector<StreamBaseException>& causes,
259 sb_internal::Errors::Type error_type = sb_internal::Errors::UNKNOWNTYPE,
260 std::string type = "StreamBaseListException");
261
262 virtual ~StreamBaseListException() throw();
263
264 const std::vector<StreamBaseException> &getCauses() const { return causes; }
265 std::string getChainOfMessages() const; // chain all exception messages together
266 std::string chainAsString() const;
267
268#ifndef DOXYGEN_SKIP
269 void throwMyself() { throw(*this); }
270#endif
271};
272SB_NAMESPACE_END;
273#endif
274
Illegal Argument.
Definition: Exceptions.hpp:228
Null value encountered.
Definition: Exceptions.hpp:231
Semantically invalid XML (e.g., box doesn't have a type).
Definition: Exceptions.hpp:204
Non-well-formed XML.
Definition: Exceptions.hpp:201
A dequeued result was not available in the time allowed.
Definition: Exceptions.hpp:225
The base class for all StreamBaseExceptions.
Definition: Exceptions.hpp:43
StreamBaseException(std::string code, std::string message, sb_internal::Errors::Type error_type=sb_internal::Errors::UNKNOWNTYPE, std::string type="StreamBaseException")
Constructor.
StreamBaseException(std::string code, std::string message, StreamBaseException &c, sb_internal::Errors::Type error_type=sb_internal::Errors::UNKNOWNTYPE, std::string type="StreamBaseException")
Constructor.
virtual ~StreamBaseException()
Destructor.
Miscellaneous illegal argument.
Definition: Exceptions.hpp:210
An Exception which contains a list of cause exceptions.
Definition: Exceptions.hpp:252
A network (TCP/IP) error was encountered.
Definition: Exceptions.hpp:219
Requested an entity which doesn't exist.
Definition: Exceptions.hpp:198
A feature is not implemented.
Definition: Exceptions.hpp:213
A feature is not supported.
Definition: Exceptions.hpp:216
A network timeout error was encountered.
Definition: Exceptions.hpp:222
Typechecking failed.
Definition: Exceptions.hpp:207
An XML/RPC error has occurred.
Definition: Exceptions.hpp:234