X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Utils%2FException.hh;h=efb44f4ab356708b798d1a0d5c7b30c7942cae75;hb=2246ca853064965a7b263c49597c4e74397b989b;hp=37f18d3dd783dc30226bd316271db21d15f97bd0;hpb=0677340b2a3f17c99808bc848f4106453a43aba0;p=senf.git diff --git a/Utils/Exception.hh b/Utils/Exception.hh index 37f18d3..efb44f4 100644 --- a/Utils/Exception.hh +++ b/Utils/Exception.hh @@ -1,9 +1,9 @@ // $Id$ // // Copyright (C) 2006 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) -// Stefan Bund +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -29,48 +29,157 @@ // Custom includes #include #include +#include +#include +#include +#include +#include //#include "Exception.mpp" ///////////////////////////////hh.p//////////////////////////////////////// -namespace senf { +/** \defgroup exception System exceptions - /** \brief Exception handling standard UNIX errors (errno) + The senf::SystemException class and it's derived class template senf::ErrnoException are used to + signal generic system failures based on \c errno codes. + + senf::SystemException is a generic \c errno based exception which carries an error number and + origin information. senf::ErrnoException is a derived class specialized for a specific error + code. This simplifies managing error conditions: + + \code + try { + something.open(path); + // ... + } + catch (senf::ErrnoException & e) { + // Create new file + } + catch (senf::SystemException & e) { + // Catch all other system exceptions + std::cerr << "Error accessing '" << path << "': " << e.what() << std::endl; + } + \endcode - This exception is thrown to signal generic errno failures. + This exception is normally thrown using the senf::throwErrno() helper: - \todo make where and err accessors and make the member vars private + \code + if ((fd = ::open(path.c_str(), O_RDWR)) < 0) + senf::throwErrno("::open()"); + \endcode - \idea Add a template class derived from SystemException which - takes the error number as a numeric argument. This allows - catching specific errno conditions: ErrnoException etc. + The senf::throwErrno() helper will throw the correct exception class based on some \c errno + value. + */ + +namespace senf { + + /** \brief Exception handling standard UNIX errors (errno) - \idea Add a generic error thrower which takes the origin - string and errno value as an argument and will throw a - corresponding template class instance. This would just be a - big switch statement containing all possible errno values, - probably created using some macro metaprogramming. + This exception is thrown to signal generic \c errno failures. + + This exception cannot be thrown directly. Instead the derived class ErrnoException should be + thrown via one of the senf::throwErrno helpers. + + The error message associated with the SystemException may be extended arbitrarily by using + the exception like a stream: + \code + try { + // This throw would normally be within some function called from here. + senf::throwErrno("::open()"); + + // Or you may want to use a more descriptive argument string: + senf::throwErrno("::open(\"" + filename + "\")"); + + // Or even use boost::format here + senf::throwErrno((boost::format("::open(\"%s\")") % filename).str()); + } + catch (SystemException & e) { + // You can add further error information later by catching and re-throwing the exception + e << " [while operating on user '" << user << "']"; + throw; + } + \endcode + + \see ErrnoException + \ingroup exception */ - class SystemException : public std::exception + class SystemException : public std::exception, public std::stringstream { public: - explicit SystemException(int err); ///< SystemException without error lokus info - /**< \param[in] err error number (the errno value) */ - SystemException(char const * where, int err); ///< SystemException with error location info - /**< \param[in] where description of error origin - \param[in] err error number (the errno value) */ - virtual char const * what() const throw(); ///< Return verbose error description - char const * where; ///< Error origin - int err; ///< Error number + int errorNumber() const; ///< Error code (\c errno number) + char const * description() const; ///< Error description (strerror() value) + + bool anyOf(int c0, int c1=0, int c2=0, int c3=0, int c4=0, int c5=0, + int c6=0, int c7=0, int c8=0, int c9=0); + ///< \c true, if errorNumber() is one of \a c0 ... \a c9 virtual ~SystemException() throw(); + + protected: + SystemException(std::string const & where, int code); + SystemException(SystemException const & other); + private: - void init(); - std::string buffer_; + int const code_; // This must be const to make the derived ErrnoException + // class a valid derived class. + mutable std::string buffer_; + + friend void throwErrno(std::string const &, int); }; + /** \brief Error specific system exception + + This template restricts the generic SystemException to a specific, compile-time constant + error number \p Code. This allows a specific \c errno number to be cached explicitly. + + This exception is normally thrown via one of the senf::throwErrno() helpers. These helpers + take the numeric \c errno value (either from the \c errno variable or from their + argument) and will throw the corresponding ErrnoException: + \code + if ((fd = ::open(filename, O_RDWR)) < 0) + senf::throwErrno("open()"); + \endcode + + \see SystemException + + \ingroup exception + */ + template + class ErrnoException : public SystemException + { + public: + static int const fixed_code = Code; + + explicit ErrnoException(std::string const & where); + ///< ErrnoException with error location information + + ErrnoException(ErrnoException const & other); + }; + + + /** \brief Throw ErrnoException based on current \c errno value + \ingroup exception + */ + void throwErrno(); + + /** \brief Throw ErrnoException based on current \c errno value (with location info) + \ingroup exception + */ + void throwErrno(std::string const & where); + + /** \brief Throw ErrnoException based on given \c errno value + \ingroup exception + */ + void throwErrno(int code); + + /** \brief Throw ErrnoException based on given \c errno value (with location info) + \ingroup exception + */ + void throwErrno(std::string const & where, int code); + enum NoThrow_t { nothrow }; } @@ -78,7 +187,7 @@ namespace senf { ///////////////////////////////hh.e//////////////////////////////////////// #include "Exception.cci" //#include "Exception.ct" -//#include "Exception.cti" +#include "Exception.cti" #endif