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