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 #if BOOST_VERSION >= 104700
00023 #include <boost/units/io.hpp>
00024 #endif
00025 #include <pion/config.hpp>
00026
00027
00028 namespace pion {
00029
00030
00031
00032
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
00089
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 {
00103
00104
00105
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
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 }
00216
00217 }
00218
00219 #endif