//****************************************************************************** // RCF - Remote Call Framework // Copyright (c) 2005 - 2007. All rights reserved. // Consult your license for conditions of use. // Developed by Jarl Lindrud. // Contact: jlindrud@hotmail.com . //****************************************************************************** #ifndef INCLUDE_RCF_EXCEPTION_HPP #define INCLUDE_RCF_EXCEPTION_HPP #include #include #include #include #include namespace RCF { // RCF error codes // range 0-1000 reserved for RCF, remaining range can be used independently of RCF static const int RcfError_Ok = 0; static const int RcfError_Unspecified = 1; static const int RcfError_ServerMessageLength = 2; static const int RcfError_ClientMessageLength = 3; static const int RcfError_Serialization = 4; static const int RcfError_Deserialization = 5; static const int RcfError_UserModeException = 6; static const int RcfError_UnknownEndpoint = 8; static const int RcfError_EndpointPassword = 9; static const int RcfError_EndpointDown = 10; static const int RcfError_EndpointRetry = 11; static const int RcfError_ClientConnectTimeout = 16; static const int RcfError_PeerDisconnect = 17; static const int RcfError_ClientCancel = 18; static const int RcfError_StubAssignment = 19; static const int RcfError_PayloadFilterMismatch = 20; static const int RcfError_OpenSslFilterInit = 21; static const int RcfError_OpenSslLoadCert = 22; static const int RcfError_UnknownPublisher = 23; static const int RcfError_UnknownFilter = 24; static const int RcfError_NoServerStub = 25; static const int RcfError_Sspi = 26; static const int RcfError_SspiAuthFail = 27; static const int RcfError_SspiInit = 28; static const int RcfError_UnknownSubscriber = 29; static const int RcfError_ClientReadTimeout = 30; static const int RcfError_ClientReadFail = 31; static const int RcfError_ClientWriteTimeout = 32; static const int RcfError_ClientWriteFail = 33; static const int RcfError_ClientConnectFail = 34; static const int RcfError_Filter = 35; static const int RcfError_Socket = 36; static const int RcfError_FnId = 37; static const int RcfError_UnknownInterface = 38; static const int RcfError_NoEndpoint = 39; static const int RcfError_TransportCreation = 40; static const int RcfError_FilterCount = 41; static const int RcfError_FilterMessage = 42; static const int RcfError_UnfilterMessage = 43; static const int RcfError_SspiCredentials = 44; static const int RcfError_SspiEncrypt = 45; static const int RcfError_SspiDecrypt = 46; static const int RcfError_SspiImpersonation = 47; static const int RcfError_NotConnected = 48; static const int RcfError_SocketClose = 49; static const int RcfError_ZlibDeflate = 50; static const int RcfError_ZlibInflate = 51; static const int RcfError_Zlib = 52; static const int RcfError_UnknownSerializationProtocol = 53; static const int RcfError_InvalidErrorMessage = 54; static const int SfError_NoCtor = 55; static const int SfError_RefMismatch = 56; static const int SfError_DataFormat = 57; static const int SfError_ReadFailure = 58; static const int SfError_WriteFailure = 59; static const int SfError_BaseDerivedRegistration = 60; static const int SfError_TypeRegistration = 61; static const int RcfError_BadException = 62; static const int RcfError_SocketBind = 63; static const int RcfError_Decoding = 64; static const int RcfError_Encoding = 65; static const int RcfError_TokenRequestFailed = 66; static const int RcfError_ObjectFactoryNotFound = 67; static const int RcfError_PortInUse = 68; static const int RcfError_DynamicObjectNotFound = 69; static const int RcfError_VersionMismatch = 70; static const int RcfError_RepeatedRetries = 71; static const int RcfError_SslCertVerification = 72; static const int RcfError_OutOfBoundsLength = 73; static const int RcfError_User = 1001; // RCF subsystem identifiers static const int RcfSubsystem_None = 0; static const int RcfSubsystem_Os = 1; static const int RcfSubsystem_Zlib = 2; static const int RcfSubsystem_OpenSsl = 3; static const int RcfSubsystem_Asio = 4; std::string getErrorString(int rcfError); std::string getSubSystemName(int subSystem); std::string getOsErrorString(int osError); /// Base class of all exceptions thrown by RCF. class Exception : public std::runtime_error { public: Exception() : std::runtime_error(""), mWhat(), mError(RCF_DEFAULT_INIT), mSubSystemError(RCF_DEFAULT_INIT), mSubSystem(RCF_DEFAULT_INIT) {} Exception(const std::string &what, const std::string &context = "") : std::runtime_error(""), mWhat(what), mContext(context), mError(RcfError_Unspecified), mSubSystemError(RCF_DEFAULT_INIT), mSubSystem(RCF_DEFAULT_INIT) {} Exception( int error, const std::string &what = "", const std::string &context = "") : std::runtime_error(""), mWhat(what), mContext(context), mError(error), mSubSystemError(RCF_DEFAULT_INIT), mSubSystem(RCF_DEFAULT_INIT) {} Exception( int error, int subSystemError, int subSystem, const std::string &what = "", const std::string &context = "") : std::runtime_error(""), mWhat(what), mContext(context), mError(error), mSubSystemError(subSystemError), mSubSystem(subSystem) {} ~Exception() throw() {} const char *what() const throw() { mTranslatedWhat = translate(); return mTranslatedWhat.c_str(); } int getError() const { return mError; } int getSubSystemError() const { return mSubSystemError; } int getSubSystem() const { return mSubSystem; } void setContext(const std::string &context) { mContext = context; } std::string getContext() const { return mContext; } void setWhat(const std::string &what) { mWhat = what; } std::string getWhat() const { return mWhat; } protected: std::string translate() const { //return getErrorString(mError) + " (" + mWhat + ")"; std::string osErr; // TODO: retrieve error messages from other subsystems as well if (mSubSystem == RcfSubsystem_Os) { osErr = getOsErrorString(mSubSystemError); } std::ostringstream os; os << "[" << mError << ": " << getErrorString(mError) << "]" << "[" << mSubSystem << ": " << getSubSystemName(mSubSystem) << "]" << "[" << mSubSystemError << ": " << osErr << "]" << "[What: " << mWhat << "]" << "[Context: " << mContext << "]"; return os.str(); } // protected to make serialization of RemoteException simpler protected: std::string mWhat; std::string mContext; int mError; int mSubSystemError; int mSubSystem; mutable std::string mTranslatedWhat; }; class RemoteException : public Exception { public: RemoteException() {} RemoteException( int remoteError, const std::string &remoteWhat = "", const std::string &remoteContext = "", const std::string &remoteExceptionType = "") : Exception( remoteError, remoteWhat, remoteContext), mRemoteExceptionType(remoteExceptionType) {} RemoteException( int remoteError, int remoteSubSystemError, int remoteSubSystem, const std::string &remoteWhat = "", const std::string &remoteContext = "", const std::string &remoteExceptionType = "") : Exception( remoteError, remoteSubSystemError, remoteSubSystem, remoteWhat, remoteContext), mRemoteExceptionType(remoteExceptionType) {} ~RemoteException() throw() {} const char *what() const throw() { mTranslatedWhat = "[Remote]" + translate(); return mTranslatedWhat.c_str(); } std::string getRemoteExceptionType() const { return mRemoteExceptionType; } template void serialize(Archive &ar, const unsigned int) { ar & mWhat & mContext & mError & mSubSystemError & mSubSystem & mRemoteExceptionType; } virtual void throwCopy() const; private: std::string mRemoteExceptionType; }; #define RCF_DEFINE_EXCEPTION(E, PE) \ class E : public PE \ { \ public: \ E( \ const std::string &what = "") : \ PE(RcfError_Unspecified, what) \ {} \ E( \ int error, \ const std::string &what = "") : \ PE(error, what) \ {} \ E( \ int error, \ int subSystemError, \ int subSystem, \ const std::string &what = "") : \ PE(error, subSystemError, subSystem, what) \ {} \ ~E() throw() \ {} \ }; RCF_DEFINE_EXCEPTION(SerializationException, Exception) RCF_DEFINE_EXCEPTION(AssertionFailureException, Exception) RCF_DEFINE_EXCEPTION(FilterException, Exception) class VersioningException : public RemoteException { public: VersioningException(int version) : RemoteException(RcfError_VersionMismatch), mVersion(version) {} ~VersioningException() throw() {} int getVersion() const { return mVersion; } private: int mVersion; }; #undef RCF_DEFINE_EXCEPTION } // namespace RCF // TODO: this should be in RcfServer.cpp, I think #include #include RCF_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION( RCF::RemoteException ) RCF_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION( std::auto_ptr ) #endif // ! INCLUDE_RCF_EXCEPTION_HPP