X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Utils%2FException.hh;h=7d56245b964cb12b4e60f6722451a9340193e2e0;hb=5924d77edecbcaff60821afb9fd13169b0a2e2ec;hp=b19c2db85d6004da3071040bfef194e83b39a75f;hpb=85dd621b12b8c974b132e6af0818f64a029b081d;p=senf.git diff --git a/Utils/Exception.hh b/Utils/Exception.hh index b19c2db..7d56245 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,147 +29,152 @@ // Custom includes #include #include +#include +#include #include #include +#include //#include "Exception.mpp" ///////////////////////////////hh.p//////////////////////////////////////// -/** \defgroup exception System exceptions +/** \defgroup exception Exception classes - 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: + All exceptions in %senf are derived from senf::Exception. This class adds the possibility to + extend the exception description while it is processed: \code try { - something.open(path); - // ... - } - catch (senf::ErrnoException & e) { - // Create new file + + // Some code which might raise an arbitrary senf exception + } - catch (senf::SystemException & e) { - // Catch all other system exceptions - std::cerr << "Error accessing '" << path << "': " << e.what() << std::endl; + catch (senf::Exception & e) { + e << "\handling user " << user; + throw; } \endcode - This exception is normally thrown using the senf::throwErrno() helper: + This will add the user information to any %senf exception thrown. The Exception is however not a + stream. If you need to do more extensive formating, either use an intermediate string-stream or + use Boost.Format: \code - if ((fd = ::open(path.c_str(), O_RDWR)) < 0) - senf::throwErrno("::open()"); + try { + // ... + } + catch (senf::Exception & e) { + e << boost::format("\ncall id 0x%04x@%s") % id % address; + } \endcode - The senf::throwErrno() helper will throw the correct exception class based on some \c errno - value. + senf::SystemException is thrown for all operating system errors (failures which result in the + operating system setting the errno value). It is also derived from senf::Exception and can + therefore be extended as well. + + Defining your own exception classes derived from senf::Exception is very simple: + + \code + struct FooException : public senf::Exception + { FooException() : senf::Exception("Foo hit the fan") {} }; + \endcode */ namespace senf { - /** \brief Exception handling standard UNIX errors (errno) - - This exception is thrown to signal generic \c errno failures. In addition to the \c errno - number (the code()), this class manages optional origin information. This parameter should - be provided to further describe, in what context the exception was created. + /** \brief Generic exception base-class - This exception should not be used directly. Instead the derived class ErrnoException should - be thrown via one of the senf::throwErrno() helpers. + Exception is a generic exception base-class which allows the exception to be later extended + by catching and re-throwing it (See example in \ref exception). - \see ErrnoException \ingroup exception - */ - class SystemException : public std::exception + */ + class Exception + : public std::exception { public: - SystemException(); ///< SystemException without error location infor - /**< The error code is taken from the current value of the - global \c errno variable */ - - explicit SystemException(int code); ///< SystemException without error location info - /**< \param[in] code error number (the \c errno value) */ + /////////////////////////////////////////////////////////////////////////// + ///\name Structors and default members + ///@{ - explicit SystemException(char const * where); ///< SystemException with error location info - /**< The error code is taken from the current value of the - global \c errno variable - \param[in] where description of error origin */ + virtual ~Exception() throw(); - SystemException(char const * where, int code); ///< SystemException with error location info - /**< \param[in] where description of error origin - \param[in] code error number (the \c errno value) */ + ///@} + /////////////////////////////////////////////////////////////////////////// - virtual char const * what() const throw(); ///< Return verbose error description + virtual char const * what() const throw(); - char const * where() const; ///< Error origin - int code() const; ///< Error code (\c errno number) - char const * description() const; ///< Error description (strerror() value) + template + Exception & operator<<(Arg const & arg); ///< Extend exception description + /**< Adds \a arg converted to string to the end of the + exception description string. This operator allows to + use Exception instances like streams. The conversion is + performed using boost::lexical_cast and is + therefor identical to a streaming operation. + \see \ref exception */ - 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 code() is one of \a c0 ... \a c9 - - virtual ~SystemException() throw(); + protected: + Exception(std::string const & description = ""); ///< Initialize exception with string + /**< \a description is the initial error description + string. This should probably be a string constant + describing the exception for most derived + exceptions. */ private: - void init(); - - char const * const where_; - int const code_; // This must be const to make the derived ErrnoException - // class a valid derived class. - std::string buffer_; + std::string message_; }; - /** \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. + /** \brief Exception handling standard UNIX errors (errno) + + This exception is thrown to signal generic \c errno failures. Normally the \c errno value is + automatically taken from the \c errno variable but it may also be specified 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()"); + // Standard usage: Take \c errno from environment + throw senf::SystemException("::open()") + << " while opening configuration file: " << filename; + + // You may however explicitly specify the errno value + throw senf::SystemException("::open()", ENOFILE) + + // Or leave the location information empty + throw senf::SystemException(ENOFILE); + throw senf::SystemException(); \endcode + \ingroup exception */ - template - class ErrnoException : public SystemException + class SystemException : public Exception { public: - static int const fixed_code = Code; + /////////////////////////////////////////////////////////////////////////// + ///\name Structors and default members + ///@{ - ErrnoException(); ///< ErrnoException without error location information - explicit ErrnoException(char const * where); - ///< ErrnoException with error location information - }; + explicit SystemException(std::string const & where = ""); + explicit SystemException(int code); + SystemException(std::string const & where, int code); - - /** \brief Throw ErrnoException based on current \c errno value - \ingroup exception - */ - void throwErrno(); + virtual ~SystemException() throw(); - /** \brief Throw ErrnoException based on current \c errno value (with location info) - \ingroup exception - */ - void throwErrno(char const * where); + ///@} + /////////////////////////////////////////////////////////////////////////// + + int errorNumber() const; ///< Error code (\c errno number) + char const * description() const; ///< Error description (\c 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 - /** \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(char const * where, int code); - enum NoThrow_t { nothrow }; + private: + void init(std::string const & where, int code); + + int code_; + }; }