#include "utf.h"
-#include "log.h"
+#include "os/stack_trace.h"
#include <exception>
+#include <list>
+
#include <boost/exception/all.hpp>
#include <boost/exception/error_info.hpp>
#include <boost/throw_exception.hpp>
-
-struct _EXCEPTION_RECORD;
-struct _EXCEPTION_POINTERS;
-
-typedef _EXCEPTION_RECORD EXCEPTION_RECORD;
-typedef _EXCEPTION_POINTERS EXCEPTION_POINTERS;
+#include <boost/noncopyable.hpp>
namespace caspar {
-typedef boost::error_info<struct tag_arg_name_info, std::string> arg_name_info_t;
-typedef boost::error_info<struct tag_arg_value_info, std::string> arg_value_info_t;
-typedef boost::error_info<struct tag_msg_info, std::string> msg_info_t;
-typedef boost::error_info<struct tag_call_stack_info, std::string> call_stack_info_t;
-typedef boost::error_info<struct tag_msg_info, std::string> error_info_t;
-typedef boost::error_info<struct tag_source_info, std::string> source_info_t;
-typedef boost::error_info<struct tag_file_name_info, std::string> file_name_info_t;
+typedef boost::error_info<struct tag_arg_name_info, std::string> arg_name_info_t;
+typedef boost::error_info<struct tag_arg_value_info, std::string> arg_value_info_t;
+typedef boost::error_info<struct tag_msg_info, std::string> msg_info_t;
+typedef boost::error_info<struct tag_call_stack_info, std::string> call_stack_info_t;
+typedef boost::error_info<struct tag_error_info, std::string> error_info_t;
+typedef boost::error_info<struct tag_source_info, std::string> source_info_t;
+typedef boost::error_info<struct tag_file_name_info, std::string> file_name_info_t;
+typedef boost::error_info<struct tag_context_info, std::string> context_info_t;
template<typename T>
inline arg_name_info_t arg_name_info(const T& str) {return arg_name_info_t(u8(str));}
template<typename T>
inline source_info_t source_info(const T& str) {return source_info_t(u8(str));}
template<typename T>
-inline file_name_info_t file_name_info(const T& str) {return file_name_info_t(u8(str));}
+inline file_name_info_t file_name_info(const T& str) {return file_name_info_t(u8(str));}
+template<typename T>
+inline context_info_t context_info(const T& str) {return context_info_t(u8(str));}
typedef boost::error_info<struct tag_line_info, size_t> line_info;
typedef boost::error_info<struct tag_nested_exception_, std::exception_ptr> nested_exception;
struct caspar_exception : virtual boost::exception, virtual std::exception
{
caspar_exception(){}
- explicit caspar_exception(const char* msg) : std::exception(msg) {}
+ const char* what() const throw() override
+ {
+ return boost::diagnostic_information_what(*this);
+ }
};
struct io_error : virtual caspar_exception {};
struct invalid_argument : virtual caspar_exception {};
struct null_argument : virtual invalid_argument {};
struct out_of_range : virtual invalid_argument {};
+struct programming_error : virtual caspar_exception {};
struct bad_alloc : virtual caspar_exception {};
struct invalid_operation : virtual caspar_exception {};
struct operation_failed : virtual caspar_exception {};
struct timed_out : virtual caspar_exception {};
-struct not_supported : virtual caspar_exception {};
struct not_implemented : virtual caspar_exception {};
-class win32_exception : public std::exception
-{
-public:
- typedef const void* address;
- static void install_handler();
- static void ensure_handler_installed_for_thread(
- const char* thread_description = nullptr);
-
- address location() const { return location_; }
- unsigned int error_code() const { return errorCode_; }
- virtual const char* what() const { return message_; }
-
-protected:
- win32_exception(const EXCEPTION_RECORD& info);
- static void Handler(unsigned int errorCode, EXCEPTION_POINTERS* pInfo);
+struct user_error : virtual caspar_exception {};
+struct expected_user_error : virtual user_error {};
+struct not_supported : virtual user_error {};
-private:
- const char* message_;
-
- address location_;
- unsigned int errorCode_;
-};
+std::string get_context();
-class win32_access_violation : public win32_exception
+class scoped_context : boost::noncopyable
{
- mutable char messageBuffer_[256];
-
public:
- bool is_write() const { return isWrite_; }
- address bad_address() const { return badAddress_;}
- virtual const char* what() const;
-
-protected:
- win32_access_violation(const EXCEPTION_RECORD& info);
- friend void win32_exception::Handler(unsigned int errorCode, EXCEPTION_POINTERS* pInfo);
-
+ scoped_context();
+ scoped_context(std::string msg);
+ template <typename Str>
+ scoped_context(Str msg)
+ : scoped_context(u8(std::move(msg)))
+ {
+ }
+
+ ~scoped_context();
+ void replace_msg(std::string msg);
+ template <typename Str>
+ void replace_msg(std::string msg)
+ {
+ replace_msg(u8(std::move(msg)));
+ }
+ void clear_msg();
private:
- bool isWrite_;
- address badAddress_;
+ std::list<std::string>& for_thread_;
+ std::string* msg_;
};
-#define CASPAR_THROW_EXCEPTION(e) BOOST_THROW_EXCEPTION(e << call_stack_info(caspar::log::internal::get_call_stack()))
+#define _CASPAR_GENERATE_UNIQUE_IDENTIFIER_CAT(name, line) name##line
+#define _CASPAR_GENERATE_UNIQUE_IDENTIFIER(name, line) _CASPAR_GENERATE_UNIQUE_IDENTIFIER_CAT(name, line)
+#define CASPAR_SCOPED_CONTEXT_MSG(ctx_msg) ::caspar::scoped_context _CASPAR_GENERATE_UNIQUE_IDENTIFIER(SCOPED_CONTEXT, __LINE__)(u8(ctx_msg));
+
+#define CASPAR_THROW_EXCEPTION(e) BOOST_THROW_EXCEPTION(e << call_stack_info(caspar::get_call_stack()) << context_info(get_context()))
+
+std::string get_message_and_context(const caspar_exception& e);
}