diff --git a/doc/adding_data_at_throw.html b/doc/adding_data_at_throw.html new file mode 100644 index 0000000..7e4af8a --- /dev/null +++ b/doc/adding_data_at_throw.html @@ -0,0 +1,73 @@ + + + + + Tutorial: Adding of Arbitrary Data at the Point of the Throw + + + +
+
+
+
+ +

Boost Exception

+
+

Adding of Arbitrary Data at the Point of the Throw

+

The following example demonstrates how errno can be stored in exception objects using Boost Exception:

+
#include <boost/exception.hpp>
+#include <errno.h>
+#include <iostream>
+
+typedef boost::error_info<struct tag_errno,int> errno_info; //(1)
+
+class my_error: public boost::exception, public std::exception { }; //(2)
+
+void
+f()
+    {
+    throw my_error() << errno_info(errno); //(3)
+    }
+
+

First, we instantiate the error_info template using a unique identifier -- tag_errno, and the type of the info it identifies -- int. This provides compile-time type safety for the various values stored in exception objects.

+

Second, we define class my_error, which derives from boost::exception.

+

Finally, (3) illustrates how the typedef from (1) can be used with operator<<() to store values in exception objects at the point of the throw.

+

The stored errno value can be recovered at a later time like this:

+
// ...continued
+
+void
+g()
+    {
+    try
+        {
+        f();
+        }
+    catch(
+    my_error & x )
+        {
+        if( boost::shared_ptr<int const> err=boost::get_error_info<errno_info>(x) )
+            std::cerr << "Error code: " << *err;
+        }
+    }
+

The get_error_info() function template is instantiated with the typedef from (1), and is passed an exception object of any type that derives publicly from boost::exception. If the exception object contains the requested value, the returned shared_ptr will point to it; otherwise an empty shared_ptr is returned.

+

See also:

+ + +
+
+
+ + diff --git a/doc/adding_data_later.html b/doc/adding_data_later.html new file mode 100644 index 0000000..eea907a --- /dev/null +++ b/doc/adding_data_later.html @@ -0,0 +1,116 @@ + + + + + Tutorial: Adding of Arbitrary Data to Active Exception Objects + + + +
+
+
+
+ +

Boost Exception

+
+

Adding of Arbitrary Data to Active Exception Objects

+

Sometimes the throw site does not have all the information that is needed at the catch site to make sense of what went wrong. Here is an example:

+
#include <stdio.h>
+#include <string>
+        
+class
+file_read_error
+    {
+    public:
+
+    explicit
+    file_read_error( std::string const & fn ):
+        fn_(fn)
+        {
+        };
+
+    std::string const &
+    file_name() const
+        {
+        return fn_;
+        }
+
+    private:
+
+    std::string fn_;
+    };
+
+void
+file_read( FILE * f, void * buffer, size_t size )
+    {
+    if( size!=fread(buffer,1,size,f) )
+        throw file_read_error("????");
+    }
+

We have defined an exception class file_read_error which can store a file name, so that when we catch a file_read_error object, we know which file the failure is related to. However, the file_read function does not have the file name at the time of the throw; all it has is a FILE handle.

+

One possible solution is to not use FILE handles directly. We could have our own class file which stores both a FILE handle and a file name, and pass that to file_read(). However, this could be problematic if we communicate with 3rd party code that does not use our class file (probably because they have their own similar class.)

+

A better solution is to make class file_read_error derive (possibly indirectly) from boost::exception, and free the file_read() function from the burden of storing the file name in exceptions it throws:

+
#include <boost/exception.hpp>
+#include <stdio.h>
+#include <errno.h>
+
+typedef boost::error_info<struct tag_errno,int> errno_info;
+
+class file_read_error: public boost::exception { };
+
+void
+file_read( FILE * f, void * buffer, size_t size )
+    {
+    if( size!=fread(buffer,1,size,f) )
+        throw file_read_error() << errno_info(errno);
+    }
+

If file_read() detects a failure, it throws an exception which contains the information that is available at the time, namely the errno. Other relevant information, such as the file name, can be added in a context higher up the call stack, where it is known naturally:

+
#include <boost/exception.hpp>
+#include <boost/shared_ptr.hpp>
+#include <stdio.h>
+#include <string>
+
+typedef boost::error_info<struct tag_file_name,std::string> file_name_info;
+
+boost::shared_ptr<FILE> file_open( char const * file_name, char const * mode );
+void file_read( FILE * f, void * buffer, size_t size );
+
+void
+parse_file( char const * file_name )
+    {
+    boost::shared_ptr<FILE> f = file_open(file_name,"rb");
+    assert(f);
+    try
+        {
+        char buf[1024];
+        file_read( f.get(), buf, sizeof(buf) );
+        }
+    catch(
+    boost::exception & e )
+        {
+        e << file_name_info(file_name);
+        throw;
+        }
+    }
+

The above function is (almost) exception-neutral -- if an exception is emitted by any function call within the try block, parse_file() does not need to do any real work, but it intercepts any boost::exception object, stores the file name, and re-throws using a throw-expression with no operand (15.1.6). The rationale for catching any boost::exception object is that the file name is relevant to any failure that occurs in parse_file(), even if the failure is unrelated to file I/O.

+

As usual, the stored data can be retrieved using get_error_info().

+

See also:

+ + +
+
+
+ + diff --git a/doc/boost-exception.html b/doc/boost-exception.html index daa815a..ed6bd00 100644 --- a/doc/boost-exception.html +++ b/doc/boost-exception.html @@ -22,7 +22,7 @@

The ability to add data to exception objects after they have been passed to throw is important, because often some of the information needed to handle an exception is unavailable in the context where the failure is detected.

Boost Exception also supports cloning of exception objects, implemented non-intrusively and automatically by the boost::throw_exception() function.

Note:

-

Boost Exception was accepted as a Boost library on November 7, 2007; however it has not yet been part of an official Boost release.

+

Boost Exception was accepted as a Boost library on November 7 2007, however it has not yet been part of an official Boost release. Current version can be downloaded from Boost SVN.

Contents

  1. Tutorial
    1. Tutorial: Transporting of Arbitrary Data to the Catch Site
    2. Tutorial: Integrating Boost Exception in Existing Exception Class Hierarchies
    3. @@ -39,28 +39,28 @@
  2. Transporting of Exceptions between Threads
    1. exception_ptr
    2. -
    3. enable_exception_cloning()
    4. -
    5. clone_exception()
    6. +
    7. enable_current_exception()
    8. +
    9. current_exception()
    10. +
    11. copy_exception()
    12. rethrow_exception()
    13. unknown_exception
  3. throw_exception()
  4. Headers
    1. boost/exception.hpp
    2. -
    3. boost/exception/enable_exception_cloning.hpp
    4. +
    5. boost/exception_ptr.hpp
    6. +
    7. boost/throw_exception.hpp
    8. +
    9. boost/exception/enable_current_exception.hpp
    10. boost/exception/enable_error_info.hpp
    11. boost/exception/info.hpp
    12. boost/exception/info_tuple.hpp
    13. boost/exception/error_info.hpp
    14. boost/exception/exception.hpp
    15. -
    16. boost/throw_exception.hpp
  • Index
  • -
  • Download
  • -
  • Browse source code
  • Synopsis

    #include <boost/exception.hpp>

    @@ -128,10 +128,11 @@ boost typedef ---unspecified--- exception_ptr; template <class T> - ---unspecified--- enable_exception_cloning( T const & e ); + ---unspecified--- enable_current_exception( T const & e ); + exception_ptr current_exception(); template <class T> - exception_ptr clone_exception( T const & e ); + exception_ptr copy_exception( T const & e ); void rethrow_exception( exception_ptr const & ep ); class @@ -299,22 +300,24 @@ boost

    This macro is designed to be used with operator<<() when throwing a boost::exception, to store information about the location of the throw statement. It can be chained with other error_infos in a single throw expression.

    Transporting of Exceptions between Threads

    exception_ptr

    -

    #include <boost/exception/cloning.hpp>

    +

    #include <boost/exception_ptr.hpp>

    namespace
     boost
         {
         typedef ---unspecified--- exception_ptr;
         }
    -

    The exception_ptr type can be used to refer to a copy of a boost::exception object. It is Default Constructible, Copy Constructible, Assignable and Equality Comparable; exception_ptr's operations do not throw.

    +

    The exception_ptr type can be used to refer to a copy of an exception object. It is Default Constructible, Copy Constructible, Assignable and Equality Comparable; exception_ptr's operations do not throw.

    Two instances of exception_ptr are equivalent and compare equal if and only if they refer to the same exception.

    The default constructor of exception_ptr produces the null value of the type. The null value is equivalent only to itself.

    -

    enable_exception_cloning()

    -

    enable_current_exception()

    +

    #include <boost/exception/enable_current_exception.hpp>

    namespace
     boost
         {
         template <class T>
    -    ---unspecified--- enable_exception_cloning( T const & e );
    +    ---unspecified--- enable_current_exception( T const & e );
         }

    Requirements:

    T must have an accessible no-throw copy constructor

    @@ -329,29 +332,39 @@ my_exception: }; .... -throw boost::enable_exception_cloning(my_exception()); -

    Unless enable_exception_cloning() is called at the time an exception object is used in a throw-expression, any attempt to copy it using clone_exception() returns an exception_ptr which refers to an instance of unknown_exception.

    +throw boost::enable_current_exception(my_exception()); +

    Unless enable_current_exception() is called at the time an exception object is used in a throw-expression, any attempt to copy it using current_exception() returns an exception_ptr which refers to an instance of unknown_exception.

    Note:

    Instead of using the throw keyword directly, it is preferable to call boost::throw_exception(). This is guaranteed to throw an exception that derives from boost::exception and supports cloning.

    -

    clone_exception()

    -

    current_exception()

    +

    #include <boost/exception_ptr.hpp>

    +
    namespace
    +boost
    +    {
    +    exception_ptr current_exception();
    +    }
    +

    Requirements:

    +

    The current_exception() function must not be called outside of a catch block.

    +

    Returns:

    +
    • An exception_ptr that refers to the currently handled exception or a copy of the currently handled exception.
    • +
    • If the function needs to allocate memory and the attempt fails, it returns an exception_ptr that refers to an instance of std::bad_alloc.
    • +
    +

    Notes:

    +
    +

    copy_exception()

    +

    #include <boost/exception_ptr.hpp>

    namespace
     boost
         {
         template <class T>
    -    exception_ptr clone_exception( T const & e );
    +    exception_ptr copy_exception( T const & e );
         }
    -

    Requirements:

    -

    T must be polymorphic.

    -

    Returns:

    -
    -

    Note:

    -

    It is unspecified whether the return values of two successive calls to clone_exception() refer to the same exception object.

    +

    Effects:

    +

    As if try { throw e; } catch( ... ) { return current_exception(); }

    rethrow_exception()

    -

    #include <boost/exception/cloning.hpp>

    +

    #include <boost/exception_ptr.hpp>

    namespace
     boost
         {
    @@ -362,7 +375,7 @@ boost
     

    Throws:

    The exception to which ep refers.

    unknown_exception

    -

    #include <boost/exception/cloning.hpp>

    +

    #include <boost/exception_ptr.hpp>

    namespace
     boost
         {
    @@ -374,8 +387,7 @@ boost
             ---unspecified---
             };
         }
    -

    This type is used by the cloning support in Boost Exception.

    -

    To allow an exception to be cloned, enable_exception_cloning() must be used at the time the exception object is passed to throw. Otherwise, calling clone_exception() returns an exception_ptr which refers to an instance of unknown_exception.

    +

    This type is used by the cloning support in Boost Exception. Please see current_exception().

    Throwing Exceptions

    throw_exception()

    #include <boost/throw_exception.hpp>

    @@ -390,7 +402,7 @@ boost #endif }

    Effects:

    -
    • If BOOST_NO_EXCEPTIONS is not defined, boost::throw_exception(e) is equivalent to throw boost::enable_exception_cloning(boost::enable_error_info(e)), unless BOOST_EXCEPTION_DISABLE is defined, in which case boost::throw_exception(e) is equivalent to throw e;
    • +
      • If BOOST_NO_EXCEPTIONS is not defined, boost::throw_exception(e) is equivalent to throw boost::enable_current_exception(boost::enable_error_info(e)), unless BOOST_EXCEPTION_DISABLE is defined, in which case boost::throw_exception(e) is equivalent to throw e;
      • If BOOST_NO_EXCEPTIONS is defined, the function is left undefined, and the user is expected to supply an appropriate definition. Callers of throw_exception are allowed to assume that the function never returns; therefore, if the user-defined throw_exception returns, the behavior is undefined.

    Transporting of Exceptions between Threads

    -

    Boost Exception supports transporting of exception objects between threads through cloning. This system is similar to N2179, but because Boost Exception can not rely on language support, the use of enable_exception_cloning() at the time of the throw is required in order to use cloning.

    +

    Boost Exception supports transporting of exception objects between threads through cloning. This system is similar to N2179, but because Boost Exception can not rely on language support, the use of enable_current_exception() at the time of the throw is required in order to use cloning.

    Note:

    All exceptions emitted by the familiar function boost::throw_exception() are guaranteed to derive from boost::exception and to support cloning.

    -

    Using enable_exception_cloning() at the Time of the Throw

    +

    Using enable_current_exception() at the Time of the Throw

    Here is how cloning can be enabled in a throw-expression (15.1):

    -
    #include <boost/exception/enable_exception_cloning.hpp>
    +
    #include <boost/exception/enable_current_exception.hpp>
     #include <boost/exception/info.hpp>
     #include <stdio.h>
     #include <errno.h>
    @@ -35,12 +35,12 @@ void
     file_read( FILE * f, void * buffer, size_t size )
         {
         if( size!=fread(buffer,1,size,f) )
    -        throw boost::enable_exception_cloning(file_read_error()) <<
    +        throw boost::enable_current_exception(file_read_error()) <<
                 errno_info(errno);
         }

    Cloning and Re-throwing an Exception

    -

    When you catch a boost::exception, you can call clone_exception() to get an exception_ptr object:

    -
    #include <boost/exception/cloning.hpp>
    +

    When you catch a boost::exception, you can call current_exception() to get an exception_ptr object:

    +
    #include <boost/exception_ptr.hpp>
     #include <boost/thread.hpp>
     #include <boost/bind.hpp>
     
    @@ -55,12 +55,12 @@ worker_thread( boost::except
             error = boost::exception_ptr();
             }
         catch(
    -    boost::exception & e )
    +    ... )
             {
    -        error = boost::clone_exception(e);
    +        error = boost::current_exception();
             }
         }
    -

    In the above example, note that clone_exception() captures the original type of the exception object, even though e refers to the base type boost::exception. This original type can be thrown again using the rethrow_exception() function:

    +

    In the above example, note that current_exception() captures the original type of the exception object, even though e refers to the base type boost::exception. This original type can be thrown again using the rethrow_exception() function:

    // ...continued
     
     void
    @@ -72,11 +72,11 @@ work()
         if( error )
             boost::rethrow_exception(error);
         }
    -

    Clone_exception() could fail to copy the original exception object in the following cases:

    +

    Clone_exception() could fail to copy the original exception object in the following cases:

    -

    Regardless, the use of clone_exception() and rethrow_exception() in the above examples is well-formed.

    +

    Regardless, the use of current_exception() and rethrow_exception() in the above examples is well-formed.

    See also:

    Boost Exception
    unknown_exception
    diff --git a/doc/cloning_and_rethrowing.html b/doc/cloning_and_rethrowing.html new file mode 100644 index 0000000..cc44cf1 --- /dev/null +++ b/doc/cloning_and_rethrowing.html @@ -0,0 +1,75 @@ + + + + + Tutorial: Cloning and Re-throwing an Exception + + + +
    +
    +
    +
    + +

    Boost Exception

    +
    +

    Cloning and Re-throwing an Exception

    +

    When you catch a boost::exception, you can call current_exception() to get an exception_ptr object:

    +
    #include <boost/exception_ptr.hpp>
    +#include <boost/thread.hpp>
    +#include <boost/bind.hpp>
    +
    +void do_work(); //throws cloning-enabled boost::exceptions
    +
    +void
    +worker_thread( boost::exception_ptr & error )
    +    {
    +    try
    +        {
    +        do_work();
    +        error = boost::exception_ptr();
    +        }
    +    catch(
    +    ... )
    +        {
    +        error = boost::current_exception();
    +        }
    +    }
    +

    In the above example, note that current_exception() captures the original type of the exception object, even though e refers to the base type boost::exception. This original type can be thrown again using the rethrow_exception() function:

    +
    // ...continued
    +
    +void
    +work()
    +    {
    +    boost::exception_ptr error;
    +    boost::thread t( boost::bind(worker_thread,boost::ref(error)) );
    +    t.join();
    +    if( error )
    +        boost::rethrow_exception(error);
    +    }
    +

    Clone_exception() could fail to copy the original exception object in the following cases:

    +
    +

    Regardless, the use of current_exception() and rethrow_exception() in the above examples is well-formed.

    +

    See also:

    + + +
    +
    +
    + + diff --git a/doc/copy_exception.html b/doc/copy_exception.html new file mode 100644 index 0000000..06f3afd --- /dev/null +++ b/doc/copy_exception.html @@ -0,0 +1,47 @@ + + + + + copy_exception + + + +
    +
    +
    +
    + +

    Boost Exception

    +
    +

    copy_exception()

    +

    #include <boost/exception_ptr.hpp>

    +
    namespace
    +boost
    +    {
    +    template <class T>
    +    exception_ptr copy_exception( T const & e );
    +    }
    +

    Effects:

    +

    As if try { throw e; } catch( ... ) { return current_exception(); }

    +

    See also:

    + + +
    +
    +
    + + diff --git a/doc/current_exception.html b/doc/current_exception.html new file mode 100644 index 0000000..531aff5 --- /dev/null +++ b/doc/current_exception.html @@ -0,0 +1,57 @@ + + + + + current_exception + + + +
    +
    +
    +
    + +

    Boost Exception

    +
    +

    current_exception()

    +

    #include <boost/exception_ptr.hpp>

    +
    namespace
    +boost
    +    {
    +    exception_ptr current_exception();
    +    }
    +

    Requirements:

    +

    The current_exception() function must not be called outside of a catch block.

    +

    Returns:

    +
    • An exception_ptr that refers to the currently handled exception or a copy of the currently handled exception.
    • +
    • If the function needs to allocate memory and the attempt fails, it returns an exception_ptr that refers to an instance of std::bad_alloc.
    • +
    +

    Notes:

    +
    +

    See also:

    + + +
    +
    +
    + + diff --git a/doc/enable_current_exception.html b/doc/enable_current_exception.html new file mode 100644 index 0000000..7ae76ed --- /dev/null +++ b/doc/enable_current_exception.html @@ -0,0 +1,64 @@ + + + + + enable_current_exception + + + +
    +
    +
    +
    + +

    Boost Exception

    +
    +

    enable_current_exception()

    +

    #include <boost/exception/enable_current_exception.hpp>

    +
    namespace
    +boost
    +    {
    +    template <class T>
    +    ---unspecified--- enable_current_exception( T const & e );
    +    }
    +

    Requirements:

    +

    T must have an accessible no-throw copy constructor

    +

    Returns:

    +

    An object of unspecified type which derives publicly from T. That is, the returned object can be intercepted by a catch(T &).

    +

    Description:

    +

    This function is designed to be used directly in a throw-expression to enable the cloning support in Boost Exception. For example:

    +
    class
    +my_exception:
    +    public std::exception
    +    {
    +    };
    +
    +....
    +throw boost::enable_current_exception(my_exception());
    +

    Unless enable_current_exception() is called at the time an exception object is used in a throw-expression, any attempt to copy it using current_exception() returns an exception_ptr which refers to an instance of unknown_exception.

    +

    Note:

    +

    Instead of using the throw keyword directly, it is preferable to call boost::throw_exception(). This is guaranteed to throw an exception that derives from boost::exception and supports cloning.

    +

    See also:

    + + +
    +
    +
    + + diff --git a/doc/exception.html b/doc/exception.html index 67c53c3..daddee2 100644 --- a/doc/exception.html +++ b/doc/exception.html @@ -68,11 +68,10 @@ boost

    See also:

    Boost Exception

    -

    boost/exception/cloning.hpp

    +

    boost/exception_ptr.hpp

    This header file contains the following definitions/declarations:

    -
    -

    boost/exception/enable_exception_cloning.hpp

    +

    boost/exception/enable_current_exception.hpp

    This header file contains the following definitions/declarations:

    -
    enable_exception_cloning
    +