00001
00002
00003
00004
00005
00006
00007
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 #include <pion/config.hpp>
00023
00024
00025 namespace pion {
00026
00027
00028
00029
00030
00031 class exception
00032 : public virtual std::exception, public virtual boost::exception
00033 {
00034 public:
00035 exception() {}
00036 exception(const std::string& msg) : m_what_msg(msg) {}
00037 exception(const char * const msg) : m_what_msg(msg) {}
00038 virtual ~exception() throw () {}
00039 virtual const char* what() const throw() {
00040 if (m_what_msg.empty()) update_what_msg();
00041 return m_what_msg.c_str();
00042 }
00043 protected:
00044 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 {
00045 std::ostringstream tmp;
00046 #if BOOST_VERSION >= 104700
00047 tmp << ( msg ? msg : boost::units::detail::demangle(BOOST_EXCEPTION_DYNAMIC_TYPEID(*this).type_->name()) );
00048 #else
00049 tmp << ( msg ? msg : boost::units::detail::demangle(BOOST_EXCEPTION_DYNAMIC_TYPEID(*this).type_.name()) );
00050 #endif
00051 if (arg1 || arg2 || arg3) tmp << ':';
00052 if (arg1) tmp << ' ' << *arg1;
00053 if (arg2) tmp << ' ' << *arg2;
00054 if (arg3) tmp << ' ' << *arg3;
00055 m_what_msg = tmp.str();
00056 }
00057 virtual void update_what_msg() const { set_what_msg(); }
00058 mutable std::string m_what_msg;
00059 };
00060
00061
00068 template <class T>
00069 static inline std::string
00070 diagnostic_information( T const & e )
00071 {
00072 boost::exception const * const be = dynamic_cast<const boost::exception*>(&e);
00073 std::exception const * const se = dynamic_cast<const std::exception*>(&e);
00074 std::ostringstream tmp;
00075 if (se) {
00076 tmp << se->what();
00077 } else {
00078 #if BOOST_VERSION >= 104700
00079 tmp << boost::units::detail::demangle(BOOST_EXCEPTION_DYNAMIC_TYPEID(e).type_->name());
00080 #else
00081 tmp << boost::units::detail::demangle(BOOST_EXCEPTION_DYNAMIC_TYPEID(e).type_.name());
00082 #endif
00083 }
00084 if (be) {
00085
00086
00087 char const * const * f=boost::get_error_info<boost::throw_file>(*be);
00088 if (f) {
00089 tmp << " [" << *f;
00090 if (int const * l=boost::get_error_info<boost::throw_line>(*be))
00091 tmp << ':' << *l;
00092 tmp << "]";
00093 }
00094 }
00095 return tmp.str();
00096 }
00097
00098
00099 namespace error {
00100
00101
00102
00103
00104
00106 typedef boost::error_info<struct errinfo_arg_name_,std::string> errinfo_message;
00107
00109 typedef boost::error_info<struct errinfo_arg_name_,std::string> errinfo_arg_name;
00110
00112 typedef boost::error_info<struct errinfo_file_name_,std::string> errinfo_file_name;
00113
00115 typedef boost::error_info<struct errinfo_dir_name_,std::string> errinfo_dir_name;
00116
00118 typedef boost::error_info<struct errinfo_plugin_name_,std::string> errinfo_plugin_name;
00119
00121 typedef boost::error_info<struct errinfo_dir_name_,std::string> errinfo_symbol_name;
00122
00123
00124
00125
00126
00127
00129 class bad_arg : public pion::exception {
00130 virtual void update_what_msg() const {
00131 set_what_msg("bad argument", boost::get_error_info<errinfo_arg_name>(*this));
00132 }
00133 };
00134
00136 class bad_config : public pion::exception {
00137 virtual void update_what_msg() const {
00138 set_what_msg("config parser error", boost::get_error_info<errinfo_file_name>(*this));
00139 }
00140 };
00141
00143 class open_file : public pion::exception {
00144 virtual void update_what_msg() const {
00145 set_what_msg("unable to open file", boost::get_error_info<errinfo_file_name>(*this));
00146 }
00147 };
00148
00150 class open_plugin : public pion::exception {
00151 virtual void update_what_msg() const {
00152 set_what_msg("unable to open plugin", boost::get_error_info<errinfo_plugin_name>(*this));
00153 }
00154 };
00155
00157 class read_file : public pion::exception {
00158 virtual void update_what_msg() const {
00159 set_what_msg("unable to read file", boost::get_error_info<errinfo_file_name>(*this));
00160 }
00161 };
00162
00164 class file_not_found : public pion::exception {
00165 virtual void update_what_msg() const {
00166 set_what_msg("file not found", boost::get_error_info<errinfo_file_name>(*this));
00167 }
00168 };
00169
00171 class directory_not_found : public pion::exception {
00172 virtual void update_what_msg() const {
00173 set_what_msg("directory not found", boost::get_error_info<errinfo_dir_name>(*this));
00174 }
00175 };
00176
00178 class plugin_not_found : public pion::exception {
00179 virtual void update_what_msg() const {
00180 set_what_msg("plugin not found", boost::get_error_info<errinfo_plugin_name>(*this));
00181 }
00182 };
00183
00185 class duplicate_plugin : public pion::exception {
00186 virtual void update_what_msg() const {
00187 set_what_msg("duplicate plugin", boost::get_error_info<errinfo_plugin_name>(*this));
00188 }
00189 };
00190
00192 class plugin_missing_symbol : public pion::exception {
00193 virtual void update_what_msg() const {
00194 set_what_msg("missing plugin symbol", boost::get_error_info<errinfo_symbol_name>(*this));
00195 }
00196 };
00197
00199 class plugin_undefined : public pion::exception {
00200 virtual void update_what_msg() const {
00201 set_what_msg("plugin has undefined state");
00202 }
00203 };
00204
00206 class bad_password_hash : public pion::exception {
00207 virtual void update_what_msg() const {
00208 set_what_msg("bad password hash");
00209 }
00210 };
00211
00212 }
00213
00214 }
00215
00216 #endif