Logo Search packages:      
Sourcecode: launchtool version File versions  Download package

Exception.h

Go to the documentation of this file.
#ifndef EXCEPTION_H
#define EXCEPTION_H

#include <string>
#include <stringf.h>

/*! \file
 * This file provides the root of the exception hierarchy.  The goal of this
 * hierarchy is to provide the most possible information on what caused the
 * exception at the least possible cost for the programmer.
 * 
 * Every exception is the descendent of Exception that, in turn, extends the
 * std::exception class of the STL.
 *
 * Further descendents of Exception add functionality and automatisms to error
 * message generation:
 *
 *  - ContextException extends Exception to provide informations on the context
 *    in which the exception was raised
 *  - ConsistencyCheckException extends ContextException to be a base class for
 *    all exception raised on failure of a consistency check;
 *    IndexOutOfRangeException is one example of such exceptions, to be used
 *    when checking that a value (such as an index) fails betweed two given
 *    bounds.
 *  - SystemException extends ContextException to carry informations about
 *    error conditions reported by external services, like the Operating
 *    System, a database interface or an interface used to communicate to some
 *    network server.  In particular, it provides the logic needed to make use
 *    of the error descriptions provided by the external services, as
 *    strerror(3) does for the operating system's error conditions.
 *    FileException is an example of such exceptions, to be used to report
 *    error conditions happened during File I/O.
 * 
 * Example exception raising:
 * \code
 *          void MyFile::open(const char* fname) throw (FileException)
 *          {
 *                if ((fd = open(fname, O_RDONLY)) == -1)
 *                      throw FileException(errno, stringf::fmt("opening %s read-only", fname));
 *          }
 * \endcode
 *
 * Example exception catching:
 * \code
 *      try {
 *                myfile.open("/tmp/foo");
 *          } catch (FileException& e) {
 *                fprintf(stderr, "%.*s: aborting.\n", PFSTR(e.toString()));
 *                exit(1);
 *          }
 * \endcode
 */

/// Basic unexpected handler
/**
 * This is an unexpected handler provided by the library.  It prints to stderr
 * a stack trace and all possible available informations about the escaped
 * exception.
 *
 * To have the function names in the stack trace, the executables need to be
 * linked using the -rdynamic flag.
 */
void DefaultUnexpected();

/// Install an unexpected handler for the duration of its scope.  Install
/// DefaultUnexpected if no handler is provided.
00067 class InstallUnexpected
{
protected:  
      void (*old)();
public:
      InstallUnexpected(void (*func)() = DefaultUnexpected);
      ~InstallUnexpected();
};

/// Base class for all exceptions
/**
 * This is the base class for all exceptions used in the system.  It provides
 * an interface to get a (hopefully detailed) textual description of the
 * exception, and a tag describing the type of exception.  Further
 * functionality will be provided by subclassers
 */
00083 class Exception
{
public:
      Exception() throw () {}
      virtual ~Exception() throw () {}
      Exception(const Exception& e) throw () {}

      /// Get a string tag identifying the exception type
00091       virtual const char* type() const throw () { return "Exception"; }

      /// Get a string describing what happened that threw the exception
00094       virtual std::string desc() const throw () { return type(); }
};

/// Exception with a description of the throwing context
00098 class ContextException : public Exception
{
protected:
      std::string _context;

public:
      /** Construct the ContextException, providing the context description in
       * printf syntax.  The context should be phrased like "Bad thing A
       * happened when doing B"
       */
00108       ContextException(const std::string& context) throw () : _context(context) {};
      ~ContextException() throw () {}

00111       virtual const char* type() const throw () { return "ContextException"; }

00113       virtual std::string desc() const throw () { return _context; }

      virtual std::string context() const throw () { return _context; }
};

/// Exception thrown when some long event is interrupted by an external event
/// (like a system call being interrupted by a signal)
/**
 * It is a direct child of ContextException, and has the very same semantics.
 *
 * \warning Any function throwing InterruptedException must allow to be called
 * again with the same parameters to retry the operation
 */
00126 class InterruptedException : public ContextException
{
public:
      InterruptedException(const std::string& context) throw () :
            ContextException(context) {}

00132       virtual const char* type() const throw ()
      {
            return "InterruptedException";
      }
};

/// Exception thrown when some system wait is interrupted by a signal
/**
 * It is a direct child of InterruptedException, and has the very same
 * semantics.
 *
 * \warning Any function throwing WaitInterruptedException must allow to be
 * called again with the same parameters to retry the operation
 */
00146 class WaitInterruptedException : public InterruptedException
{
public:
      WaitInterruptedException(const std::string& context) throw () :
            InterruptedException(context) {}

00152       virtual const char* type() const throw ()
      {
            return "WaitInterruptedException";
      }
};

/// Exception thrown when some consistency check fails
/**
 * It is a direct child of ContextException, and has the very same semantics.
 */
00162 class ConsistencyCheckException : public ContextException
{
public:
      ConsistencyCheckException(const std::string& context) throw () :
            ContextException(context) {}

00168       virtual const char* type() const throw ()
      {
            return "ConsistencyCheckException";
      }
};

class OutOfRangeException : public ConsistencyCheckException
{
protected:
      std::string _var_desc;

public:
      OutOfRangeException(const std::string& context, const std::string& var_desc) throw ()
            : ConsistencyCheckException(context), _var_desc(var_desc) {}
      ~OutOfRangeException() throw () {}

      virtual const char* type() const throw ()
      {
            return "ConsistencyCheckException";
      }

      /// Get a short description of the variable that has been checked
      virtual std::string var_desc() const throw () { return _var_desc; }

      virtual std::string desc() const throw ()
      {
            return _var_desc + " out of range " + _context;
      }
};

/// Exception thrown when index checking fails
/**
 * This exception is to be thrown when an index checking fails, providing
 * informations on the acceptable index range and on the offending value.
 * The context should be a description of the index, possibly preceeded by a
 * description of in what context did the index checking happen.
 * 
 * Example:
 * \code
 *  if (age < 18)
 *     throw IndexOutOfRangeException(age, 18, 0,
 *                                              "obtaining driver license, age");
 *
 *  if (i < 0 || i > 100)
 *    throw IndexOutOfRangeException(i, 0, 100, "percentage of items sold");
 * \endcode
 */
template <class C>
00216 class ValOutOfRangeException : public OutOfRangeException
{
protected:
      C _val;
      C _inf;
      C _sup;

public:
      /** Construct the exception; minBound and maxBound are the bounds of the
       * valid index range (inclusive).
       */
00227       ValOutOfRangeException(const std::string& context, const std::string& var_desc,
                                    C val, C inf, C sup) throw ()
                              : OutOfRangeException(context, var_desc),
                                    _val(val), _inf(inf), _sup(sup) {}
      
      ///@name Methods used to get informations about the index and its bounds
      //@{
      /// Get the value that caused the index to go out-of-bounds
00235       virtual C val() const throw () { return _val; }
      /// Get the minimum allowed value for this index
00237       virtual C inf() const throw () { return _inf; }
      /// Get the maximum allowed value for this index
00239       virtual C sup() const throw () { return _sup; }
      //@}

00242       virtual const char* type() const throw ()
      {
            return "ValOutOfRangeException<>";
      }

00247       virtual std::string desc() const throw ()
      {
            return _var_desc + "(" + stringf::fmt(_val) + ") out of range (" +
                        stringf::fmt(_inf) + "-" + stringf::fmt(_sup) + ") " + _context;
      }
};

/// Base class for system exceptions
/**
 * This is the base class for exceptions that depend on system events, like
 * exceptions on file or network I/O, on database access and so on.
 * SystemExceptions introduces the keeping of an error code with an associated
 * string description, and by defaults provides the textual description for
 * Unix errno error codes.
 * The exception context should be phrased like "doing X".
 *
 * Example:
 * \code
 *          const char* fname = "foo.bar";
 *          if ((fd = open(fname, O_RDONLY)) == -1)
 *                // Should not throw SystemException, but a more specialized derived
 *                // class like FileException
 *                throw SystemException(errno, stringf::fmt("opening %s read-only", fname));
 * \endcode
 */
00272 class SystemException : public ContextException
{
protected:
      int _code;

public:
      SystemException(int code, const std::string& context) throw () :
            ContextException(context), _code(code) {}

00281       virtual const char* type() const throw () { return "SystemException"; }

      /// Get the system error code associated to the exception
00284       virtual int code() const throw () { return _code; }

      /// Get the description of the error code
      virtual std::string system_desc() const throw ();

00289       virtual std::string desc() const throw ()
      {
            return system_desc() + " " + _context;
      }
};

/// Base class for exceptions for file I/O
/**
 * It is a direct child of SystemException, and has the very same semantics.
 * Like in SystemException, the error code description provided is a
 * description for errno values.
 */
00301 class FileException : public SystemException
{
public:
      FileException(int code, const std::string& context)   throw () :
            SystemException(code, context) {}

00307       virtual const char* type() const throw () { return "FileException"; }
};

// vim:set ts=4 sw=4:
#endif

Generated by  Doxygen 1.6.0   Back to index