1 /*-
2  * Copyright (c) 2009, 2020 Oracle and/or its affiliates.  All rights reserved.
3  *
4  * See the file LICENSE for license information.
5  *
6  * $Id$
7  */
8 
9 #ifndef _DB_STL_EXCEPTION_H
10 #define _DB_STL_EXCEPTION_H
11 
12 #include <cstring>
13 #include <cstdlib>
14 #include <cstdio>
15 
16 #include <iostream>
17 #include <exception>
18 
19 #include "dbstl_common.h"
20 
21 START_NS(dbstl)
22 
23 using std::cerr;
24 
25 // Internally used only.
26 void _exported throw_bdb_exception(const char *caller, int err_ret);
27 #define COPY_CONSTRUCTOR(type) type(const type& t) : DbstlException(t){}
28 
29 /** \defgroup Exception_classes_group dbstl exception classes
30 dbstl throws several types of exceptions on several kinds of errors, the
31 exception classes form a class hiarachy. First, there is the DbstlException,
32 which is the base class for all types of dbstl specific concrete exception
33 classes.
34 DbstlException inherits from the class DbException of Berkeley DB C++ API. Since
35 DbException class inherits from C++ STL exception base class std::exception,
36 you can make use of all Berkeley DB C++ and dbstl API exceptions in the same
37 way you use the C++ std::exception class.
38 
39 Besides exceptions of DbstlException and its subclasses, dbstl may also
40 throw exceptions of DbException and its subclasses, which happens when a
41 Berkeley DB call failed. So you should use the same way you catch Berkeley DB
42 C++ API exceptions when you want to catch exceptions throw by Berkeley DB
43 operations.
44 
45 When an exception occurs, dbstl initialize an local exception object on the
46 stack and throws the exception object, so you should catch an exception like
47 this:
48 
49 try {
50 	// dbstl operations
51 }
52 catch(DbstlException ex){
53 	// Exception handling
54 	throw ex; // Optionally throw ex again
55 }
56 
57 @{
58 */
59 
60 /// Base class of all dbstl exception classes. It is derived from Berkeley
61 /// DB C++ API DbException class to maintain consistency with all
62 /// Berkeley DB exceptions.
63 ///
64 class _exported DbstlException : public DbException
65 {
66 public:
DbstlException(const char * msg)67 	explicit DbstlException(const char *msg) : DbException(msg) {}
DbstlException(const char * msg,int err)68 	DbstlException(const char *msg, int err) : DbException(msg, err) {}
DbstlException(const DbstlException & ex)69 	DbstlException(const DbstlException&ex) : DbException(ex) {}
DbstlException(int err)70 	explicit DbstlException(int err) : DbException(err) {}
DbstlException(const char * prefix,const char * msg,int err)71 	DbstlException(const char *prefix, const char *msg, int err) :
72 	    DbException(prefix, msg, err) {}
73 
74 	const DbstlException& operator=(const DbstlException&exobj)
75 	{
76 		ASSIGNMENT_PREDCOND(exobj)
77 		DbException::operator =
78 		    (dynamic_cast<const DbException&>(exobj));
79 		return exobj;
80 	}
81 
~DbstlException()82 	virtual ~DbstlException() throw(){}
83 };
84 
85 /// Failed to allocate memory because memory is not enough.
86 class _exported NotEnoughMemoryException : public DbstlException
87 {
88 	size_t failed_size; // The size of the failed allocation.
89 public:
NotEnoughMemoryException(const char * msg,size_t sz)90 	NotEnoughMemoryException(const char *msg, size_t sz)
91 	    : DbstlException(msg)
92 	{
93 		failed_size = sz;
94 	}
95 
96 
NotEnoughMemoryException(const NotEnoughMemoryException & ex)97 	NotEnoughMemoryException(const NotEnoughMemoryException &ex)
98 	    : DbstlException(ex)
99 	{
100 		this->failed_size = ex.failed_size;
101 	}
102 };
103 
104 /// The iterator has inconsistent status, it is unable to be used any more.
105 class _exported InvalidIteratorException : public DbstlException
106 {
107 public:
InvalidIteratorException()108 	InvalidIteratorException() : DbstlException("Invalid Iterator")
109 	{
110 	}
111 
InvalidIteratorException(int error_code)112 	explicit InvalidIteratorException(int error_code) :
113 	    DbstlException("Invalid Iterator", error_code)
114 	{
115 	}
116 	COPY_CONSTRUCTOR(InvalidIteratorException)
117 };
118 
119 /// The cursor has inconsistent status, it is unable to be used any more.
120 class _exported InvalidCursorException : public DbstlException
121 {
122 public:
InvalidCursorException()123 	InvalidCursorException() : DbstlException("Invalid cursor")
124 	{
125 	}
126 
InvalidCursorException(int error_code)127 	explicit InvalidCursorException(int error_code) :
128 	    DbstlException("Invalid cursor", error_code)
129 	{
130 	}
131 	COPY_CONSTRUCTOR(InvalidCursorException)
132 };
133 
134 /// The Dbt object has inconsistent status or has no valid data, it is unable
135 /// to be used any more.
136 class _exported InvalidDbtException : public DbstlException
137 {
138 public:
InvalidDbtException()139 	InvalidDbtException() : DbstlException("Invalid Dbt object")
140 	{
141 	}
142 
InvalidDbtException(int error_code)143 	explicit InvalidDbtException(int error_code) :
144 	    DbstlException("Invalid Dbt object", error_code)
145 	{
146 	}
147 	COPY_CONSTRUCTOR(InvalidDbtException)
148 };
149 
150 /// The assertions inside dbstl failed. The code file name and line number
151 /// will be passed to the exception object of this class.
152 class _exported FailedAssertionException : public DbstlException
153 {
154 private:
155 	char *err_msg_;
156 public:
what()157 	virtual const char *what() const throw()
158 	{
159 		return err_msg_;
160 	}
161 
FailedAssertionException(const char * fname,size_t lineno,const char * msg)162 	FailedAssertionException(const char *fname, size_t lineno,
163 	    const char *msg) : DbstlException(0)
164 	{
165 		u_int32_t sz;
166 		char *str;
167 
168 		str = (char *)DbstlMalloc(sz = (u_int32_t)(strlen(msg) +
169 		    strlen(fname) + 128));
170 		_snprintf(str, sz,
171 		    "In file %s at line %u, %s expression failed",
172 		    fname, (unsigned int)lineno, msg);
173 		err_msg_ = str;
174 #ifdef DEBUG
175 		fprintf(stderr, "%s", str);
176 #endif
177 	}
178 
FailedAssertionException(const FailedAssertionException & ex)179 	FailedAssertionException(const FailedAssertionException&ex) :
180 	    DbstlException(ex)
181 	{
182 		err_msg_ = (char *)DbstlMalloc((u_int32_t)
183 		    strlen(ex.err_msg_) + 1);
184 		strcpy(err_msg_, ex.err_msg_);
185 	}
~FailedAssertionException()186 	virtual ~FailedAssertionException() throw()
187 	{
188 		free(err_msg_);
189 	}
190 };
191 
192 /// There is no such key in the database. The key can't not be passed into
193 /// the exception instance because this class has to be a class template for
194 /// that to work.
195 class _exported NoSuchKeyException : public DbstlException
196 {
197 public:
NoSuchKeyException()198 	NoSuchKeyException()
199 	    : DbstlException("\nNo such key in the container.")
200 	{
201 	}
202 
203 	COPY_CONSTRUCTOR(NoSuchKeyException)
204 };
205 
206 /// Some argument of a function is invalid.
207 class _exported InvalidArgumentException : public DbstlException
208 {
209 public:
InvalidArgumentException(const char * errmsg)210 	explicit InvalidArgumentException(const char *errmsg) :
211 	    DbstlException(errmsg)
212 	{
213 #ifdef DEBUG
214 		cerr<<errmsg;
215 #endif
216 	}
217 
InvalidArgumentException(const char * argtype,const char * arg)218 	InvalidArgumentException(const char *argtype, const char *arg) :
219 	    DbstlException(argtype, arg, 0)
220 	{
221 #ifdef DEBUG
222 		cerr<<"\nInvalid argument exception: "<<argtype<<"\t"<<arg;
223 #endif
224 	}
225 
226 	COPY_CONSTRUCTOR(InvalidArgumentException)
227 };
228 
229 /// The function called is not supported in this class.
230 class _exported NotSupportedException : public DbstlException
231 {
232 public:
NotSupportedException(const char * str)233 	explicit NotSupportedException(const char *str) : DbstlException(str)
234 	{
235 	}
236 
237 	COPY_CONSTRUCTOR(NotSupportedException)
238 };
239 
240 /// The function can not be called in this context or in current configurations.
241 class _exported InvalidFunctionCall : public DbstlException
242 {
243 public:
InvalidFunctionCall(const char * str)244 	explicit InvalidFunctionCall(const char *str) : DbstlException(str)
245 	{
246 #ifdef DEBUG
247 		cerr<<"\nInvalid function call: "<<str;
248 #endif
249 	}
250 
251 	COPY_CONSTRUCTOR(InvalidFunctionCall)
252 };
253 /** @}*/
254 #undef COPY_CONSTRUCTOR
255 END_NS
256 
257 #endif //_DB_STL_EXCEPTION_H
258