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