/* * $Id$ * * (c) Copyright, Real-Time Innovations, 2016-. * All rights reserved. * No duplications, whole or partial, manual or electronic, may be made * without express written permission. Any such copies, or * revisions thereof, must display this notice unaltered. * This code contains trade secrets of Real-Time Innovations, Inc. */ #ifndef HPP_SERVICE_SERVICE_EXCEPTION_HPP_ #define HPP_SERVICE_SERVICE_EXCEPTION_HPP_ // IMPORTANT: macros.hpp must be the first RTI header included in every header // file so that symbols are exported correctly on Windows #include #include #include namespace rti { namespace apputils { static void initialize_exception_message( std::string& message, const char *throwing_context, const RTILogMessage *log_message, va_list ap) { char message_buffer[RTI_LOG_MSG_SIZE_MAX]; RTIOsapiUtility_unusedReturnValue( RTIOsapiUtility_vsnprintf( message_buffer, RTI_LOG_MSG_SIZE_MAX, log_message->format, ap), int); RTIOsapiUtility_unusedReturnValue( RTIOsapiUtility_snprintf( &message[0], RTI_LOG_MSG_SIZE_MAX, "%s:%s", throwing_context, message_buffer), int); } static void initialize_exception_message( std::string& message, const char *throwing_context, const RTILogMessageTemplate *log_message, const char *parameterizedString, va_list ap) { char message_buffer[RTI_LOG_MSG_SIZE_MAX]; const char *SEPARATOR_STR = " | "; RTIOsapiUtility_unusedReturnValue( RTIOsapiUtility_vsnprintf( message_buffer, RTI_LOG_MSG_SIZE_MAX, parameterizedString, ap), int); RTIOsapiUtility_unusedReturnValue( RTIOsapiUtility_snprintf( &message[0], RTI_LOG_MSG_SIZE_MAX, "%s%s%s:%s", throwing_context, log_message->format, strlen(log_message->format) > 0 ? SEPARATOR_STR : "", message_buffer), int); } /** * @brief Exception class for Services */ class ServiceException : public std::exception { public: ServiceException( const char *throwing_context, const RTILogMessage *log_message, ...) : message_(RTI_LOG_MSG_SIZE_MAX, '\0'), message_id_(log_message->messageId) { va_list ap; va_start(ap, log_message); initialize_exception_message( message_, throwing_context, log_message, ap); va_end(ap); } ServiceException( const char *throwing_context, const RTILogMessageTemplate *log_message, const char *parameterizedString, ...) : message_(RTI_LOG_MSG_SIZE_MAX, '\0'), message_id_(log_message->messageId) { va_list ap; va_start(ap, parameterizedString); initialize_exception_message( message_, throwing_context, log_message, parameterizedString, ap); va_end(ap); } uint32_t message_id() const { return message_id_; } virtual const char* what() const throw () { return message_.c_str(); } virtual ~ServiceException() throw () { } private: ServiceException() : message_id_(0u) { } std::string message_; std::uint32_t message_id_; }; /** * @brief Fatal exception class for Services. This exception will cause * the underlying service to call the shutdown hook. */ class FatalServiceException : public ServiceException { public: template FatalServiceException( const char *throwing_context, const RTILogMessage *log_message, Args... args) : ServiceException(throwing_context, log_message, args...) { } template FatalServiceException( const char *throwing_context, const RTILogMessageTemplate *log_message, const char *parameterizedString, Args... args) : ServiceException( throwing_context, log_message, parameterizedString, args...) { } virtual ~FatalServiceException() throw() { } }; } } /* namespace rti::apputils */ #define RTI_THROW_SERVICE_EXCEPTION(...) \ throw rti::apputils::ServiceException(\ RTI_FUNCTION_NAME,\ __VA_ARGS__) #define RTI_THROW_FATAL_SERVICE_EXCEPTION(...) \ throw rti::apputils::FatalServiceException(\ RTI_FUNCTION_NAME,\ __VA_ARGS__) #define RTI_SERVICE_CHECK_CONDITION(EXPRESSION) \ if(!(EXPRESSION)) { \ RTI_THROW_SERVICE_EXCEPTION( \ &RTI_LOG_ANY_s, \ __FILE__ ":" RTI_TOSTRING(__LINE__) ": condition failed: " #EXPRESSION); \ } #define RTI_SERVICE_CHECK_CONDITION_W_EXTRA_INFO(EXPRESSION, EXTRA_INFO) \ if(!(EXPRESSION)) { \ RTI_THROW_SERVICE_EXCEPTION( \ &RTI_LOG_ANY_ss, \ __FILE__ ":" RTI_TOSTRING(__LINE__) ": condition failed: " #EXPRESSION ", ", \ EXTRA_INFO); \ } #endif /* HPP_SERVICE_SERVICE_EXCEPTION_HPP_ */