Vault
4.1
|
00001 /* 00002 Copyright c1997-2014 Trygve Isaacson. All rights reserved. 00003 This file is part of the Code Vault version 4.1 00004 http://www.bombaydigital.com/ 00005 License: MIT. See LICENSE.md in the Vault top level directory. 00006 */ 00007 00008 #ifndef vexception_h 00009 #define vexception_h 00010 00013 #include "vstring.h" 00014 #include "vlogger.h" 00015 #include "vthread.h" 00016 00141 class VSystemError { 00142 00143 public: 00144 00149 VSystemError(); 00157 VSystemError(int errorCode); 00165 VSystemError(int errorCode, const VString& errorMessage); 00166 ~VSystemError() {} 00167 00174 static VSystemError getSocketError(); 00175 00181 int getErrorCode() const { return mErrorCode; } 00188 VString getErrorMessage() const { return mErrorMessage; } 00198 bool isLikePosixError(int posixErrorCode) const { return this->_isLikePosixError(posixErrorCode); } 00199 00200 private: 00201 00202 // Platform-specific implementations for obtaining system and socket error codes and messages. 00203 // The implementation for these is in each platform's vtypes_platform.cpp file. 00204 static int _getSystemErrorCode(); 00205 static int _getSocketErrorCode(); 00206 static VString _getSystemErrorMessage(int errorCode); 00207 00208 bool _isLikePosixError(int posixErrorCode) const; 00209 00210 int mErrorCode; 00211 VString mErrorMessage; 00212 }; 00213 00228 class VException : public std::exception { 00229 public: 00230 00235 VException(bool recordStackTrace = false); 00243 VException(const VException& other, bool recordStackTrace = false); 00250 VException(int error, const char* errorMessage, bool recordStackTrace = false); 00257 VException(int error, const VString& errorString, bool recordStackTrace = false); 00263 VException(const char* errorMessage, bool recordStackTrace = false); 00269 VException(const VString& errorString, bool recordStackTrace = false); 00277 VException(const VSystemError& error, const VString& errorString, bool recordStackTrace = false); 00282 virtual ~VException() throw(); 00283 00290 VException& operator=(const VException& other); 00291 00298 virtual const char* what() const throw(); 00299 00304 int getError() const; 00305 00306 static const int kGenericError = -1; 00307 00314 const VStringVector& getStackTrace() const; 00315 00316 private: 00317 00319 void _assertInvariant() const; 00320 00322 void _recordStackTrace(); 00323 00326 static void _breakpointLocation(); 00327 00328 int mError; 00329 VString mErrorString; 00330 const char* mErrorMessage; 00331 VStringVector mStackTrace; 00332 }; 00333 00342 class VStackTraceException : public VException { 00343 public: 00344 00345 VStackTraceException(const VString& errorString) : 00346 VException(errorString, true) {} 00347 VStackTraceException(int error, const VString& errorString) : 00348 VException(error, errorString, true) {} 00349 VStackTraceException(const VSystemError& error, const VString& errorString) : 00350 VException(error, errorString, true) {} 00351 virtual ~VStackTraceException() throw() {} 00352 }; 00353 00360 class VEOFException : public VException { 00361 public: 00362 00367 VEOFException(const char* errorMessage) : VException(errorMessage) {} 00372 VEOFException(const VString& errorString) : VException(errorString) {} 00376 virtual ~VEOFException() throw() {} 00377 }; 00378 00389 class VSocketClosedException : public VException { 00390 public: 00391 00397 VSocketClosedException(int error, const VString& errorString) : VException(error, errorString) {} 00403 VSocketClosedException(const VSystemError& error, const VString& errorString) : VException(error, errorString) {} 00407 virtual ~VSocketClosedException() throw() {} 00408 }; 00409 00416 class VRangeException : public VException { 00417 public: 00418 00424 VRangeException(const char* errorMessage, bool recordStackTrace = true) : VException(errorMessage, recordStackTrace) {} 00430 VRangeException(const VString& errorString, bool recordStackTrace = true) : VException(errorString, recordStackTrace) {} 00434 virtual ~VRangeException() throw() {} 00435 }; 00436 00441 class VUnimplementedException : public VException { 00442 public: 00443 00449 VUnimplementedException(const char* errorMessage, bool recordStackTrace = true) : VException(errorMessage, recordStackTrace) {} 00455 VUnimplementedException(const VString& errorString, bool recordStackTrace = true) : VException(errorString, recordStackTrace) {} 00459 virtual ~VUnimplementedException() throw() {} 00460 }; 00461 00462 #ifdef VAULT_CORE_FOUNDATION_SUPPORT 00463 00467 class VOSStatusException : public VException { 00468 public: 00469 00477 static void throwIfError(OSStatus err, const VString& message, bool recordStackTrace = true) { if (0 != err) throw VOSStatusException(err, message, recordStackTrace); } 00478 00486 VOSStatusException(OSStatus err, const VString& message, bool recordStackTrace = true) : VException(static_cast<int>(err), message, recordStackTrace) {} 00490 virtual ~VOSStatusException() throw() {} 00491 }; 00492 00493 #endif /* VAULT_CORE_FOUNDATION_SUPPORT */ 00494 00517 template<typename cast_to_type, typename an_object_ptr> 00518 static cast_to_type VcheckedDynamicCast(an_object_ptr& obj, const char* file, int line, bool rethrowException, bool logException, bool logStackCrawl) { 00519 try { 00520 return dynamic_cast<cast_to_type>(obj); 00521 } catch (const std::exception& ex) { 00522 // Avoid message construction overhead if no flags require it. 00523 if (logException || rethrowException) { 00524 VString message(VSTRING_ARGS("Exception in dynamic_cast operation at %s:%d: '%s'", file, line, ex.what())); 00525 00526 if (logException) { 00527 if (logStackCrawl) { 00528 VThread::logStackCrawl(message, VLogger::getDefaultLogger(), false); 00529 } 00530 00531 VLogger::getDefaultLogger()->log(VLoggerLevel::ERROR, file, line, message); 00532 } 00533 00534 if (rethrowException) { 00535 throw VException(message); 00536 } 00537 } 00538 00539 return NULL; 00540 } 00541 } 00542 00544 #define V_CHECKED_DYNAMIC_CAST(cast_to_type, an_object) VcheckedDynamicCast<cast_to_type>((an_object), __FILE__, __LINE__, true, true, true) 00545 00546 #define V_CHECKED_DYNAMIC_CAST_NOTHROW(cast_to_type, an_object) VcheckedDynamicCast<cast_to_type>((an_object), __FILE__, __LINE__, false, true, true) 00547 00548 #endif /* vexception_h */