pion
5.0.6
|
00001 // --------------------------------------------------------------------- 00002 // pion: a Boost C++ framework for building lightweight HTTP interfaces 00003 // --------------------------------------------------------------------- 00004 // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) 00005 // 00006 // Distributed under the Boost Software License, Version 1.0. 00007 // See http://www.boost.org/LICENSE_1_0.txt 00008 // 00009 00010 #ifndef __PION_ERROR_HEADER__ 00011 #define __PION_ERROR_HEADER__ 00012 00013 #include <string> 00014 #include <sstream> 00015 #include <exception> 00016 #include <boost/version.hpp> 00017 #include <boost/throw_exception.hpp> 00018 #include <boost/exception/exception.hpp> 00019 #include <boost/exception/info.hpp> 00020 #include <boost/exception/error_info.hpp> 00021 #include <boost/exception/get_error_info.hpp> 00022 #if BOOST_VERSION >= 104700 00023 #include <boost/units/io.hpp> 00024 #endif 00025 #include <pion/config.hpp> 00026 00027 00028 namespace pion { // begin namespace pion 00029 00030 // 00031 // exception: simple exception class for pion errors that generates what() 00032 // strings with more descriptive messages and optionally arguments as well 00033 // 00034 class exception 00035 : public virtual std::exception, public virtual boost::exception 00036 { 00037 public: 00038 exception() {} 00039 exception(const std::string& msg) : m_what_msg(msg) {} 00040 exception(const char * const msg) : m_what_msg(msg) {} 00041 virtual ~exception() throw () {} 00042 virtual const char* what() const throw() { 00043 if (m_what_msg.empty()) update_what_msg(); 00044 return m_what_msg.c_str(); 00045 } 00046 protected: 00047 inline void set_what_msg(const char * const msg = NULL, const std::string * const arg1 = NULL, const std::string * const arg2 = NULL, const std::string * const arg3 = NULL) const { 00048 std::ostringstream tmp; 00049 #if BOOST_VERSION >= 104700 00050 tmp << ( msg ? msg : boost::units::detail::demangle(BOOST_EXCEPTION_DYNAMIC_TYPEID(*this).type_->name()) ); 00051 #else 00052 tmp << ( msg ? msg : boost::units::detail::demangle(BOOST_EXCEPTION_DYNAMIC_TYPEID(*this).type_.name()) ); 00053 #endif 00054 if (arg1 || arg2 || arg3) tmp << ':'; 00055 if (arg1) tmp << ' ' << *arg1; 00056 if (arg2) tmp << ' ' << *arg2; 00057 if (arg3) tmp << ' ' << *arg3; 00058 m_what_msg = tmp.str(); 00059 } 00060 virtual void update_what_msg() const { set_what_msg(); } 00061 mutable std::string m_what_msg; 00062 }; 00063 00064 00071 template <class T> 00072 static inline std::string 00073 diagnostic_information( T const & e ) 00074 { 00075 boost::exception const * const be = dynamic_cast<const boost::exception*>(&e); 00076 std::exception const * const se = dynamic_cast<const std::exception*>(&e); 00077 std::ostringstream tmp; 00078 if (se) { 00079 tmp << se->what(); 00080 } else { 00081 #if BOOST_VERSION >= 104700 00082 tmp << boost::units::detail::demangle(BOOST_EXCEPTION_DYNAMIC_TYPEID(e).type_->name()); 00083 #else 00084 tmp << boost::units::detail::demangle(BOOST_EXCEPTION_DYNAMIC_TYPEID(e).type_.name()); 00085 #endif 00086 } 00087 if (be) { 00088 //char const * const * fn=boost::get_error_info<boost::throw_function>(*be); 00089 //if (fn) tmp << " at " << *fn; 00090 char const * const * f=boost::get_error_info<boost::throw_file>(*be); 00091 if (f) { 00092 tmp << " [" << *f; 00093 if (int const * l=boost::get_error_info<boost::throw_line>(*be)) 00094 tmp << ':' << *l; 00095 tmp << "]"; 00096 } 00097 } 00098 return tmp.str(); 00099 } 00100 00101 00102 namespace error { // begin namespace error 00103 00104 // 00105 // pion error info types 00106 // 00107 00109 typedef boost::error_info<struct errinfo_arg_name_,std::string> errinfo_message; 00110 00112 typedef boost::error_info<struct errinfo_arg_name_,std::string> errinfo_arg_name; 00113 00115 typedef boost::error_info<struct errinfo_file_name_,std::string> errinfo_file_name; 00116 00118 typedef boost::error_info<struct errinfo_dir_name_,std::string> errinfo_dir_name; 00119 00121 typedef boost::error_info<struct errinfo_plugin_name_,std::string> errinfo_plugin_name; 00122 00124 typedef boost::error_info<struct errinfo_dir_name_,std::string> errinfo_symbol_name; 00125 00126 00127 // 00128 // pion exception types 00129 // 00130 00132 class bad_arg : public pion::exception { 00133 virtual void update_what_msg() const { 00134 set_what_msg("bad argument", boost::get_error_info<errinfo_arg_name>(*this)); 00135 } 00136 }; 00137 00139 class bad_config : public pion::exception { 00140 virtual void update_what_msg() const { 00141 set_what_msg("config parser error", boost::get_error_info<errinfo_file_name>(*this)); 00142 } 00143 }; 00144 00146 class open_file : public pion::exception { 00147 virtual void update_what_msg() const { 00148 set_what_msg("unable to open file", boost::get_error_info<errinfo_file_name>(*this)); 00149 } 00150 }; 00151 00153 class open_plugin : public pion::exception { 00154 virtual void update_what_msg() const { 00155 set_what_msg("unable to open plugin", boost::get_error_info<errinfo_plugin_name>(*this)); 00156 } 00157 }; 00158 00160 class read_file : public pion::exception { 00161 virtual void update_what_msg() const { 00162 set_what_msg("unable to read file", boost::get_error_info<errinfo_file_name>(*this)); 00163 } 00164 }; 00165 00167 class file_not_found : public pion::exception { 00168 virtual void update_what_msg() const { 00169 set_what_msg("file not found", boost::get_error_info<errinfo_file_name>(*this)); 00170 } 00171 }; 00172 00174 class directory_not_found : public pion::exception { 00175 virtual void update_what_msg() const { 00176 set_what_msg("directory not found", boost::get_error_info<errinfo_dir_name>(*this)); 00177 } 00178 }; 00179 00181 class plugin_not_found : public pion::exception { 00182 virtual void update_what_msg() const { 00183 set_what_msg("plugin not found", boost::get_error_info<errinfo_plugin_name>(*this)); 00184 } 00185 }; 00186 00188 class duplicate_plugin : public pion::exception { 00189 virtual void update_what_msg() const { 00190 set_what_msg("duplicate plugin", boost::get_error_info<errinfo_plugin_name>(*this)); 00191 } 00192 }; 00193 00195 class plugin_missing_symbol : public pion::exception { 00196 virtual void update_what_msg() const { 00197 set_what_msg("missing plugin symbol", boost::get_error_info<errinfo_symbol_name>(*this)); 00198 } 00199 }; 00200 00202 class plugin_undefined : public pion::exception { 00203 virtual void update_what_msg() const { 00204 set_what_msg("plugin has undefined state"); 00205 } 00206 }; 00207 00209 class bad_password_hash : public pion::exception { 00210 virtual void update_what_msg() const { 00211 set_what_msg("bad password hash"); 00212 } 00213 }; 00214 00215 } // end namespace error 00216 00217 } // end namespace pion 00218 00219 #endif