Boost logo

Boost :

From: Emil Dotchevski (emil_at_[hidden])
Date: 2007-09-30 16:01:19


On 9/30/07, Tom Brinkman <reportbase_at_[hidden]> wrote:
> > 3) Support for linking multiple error tags in a single expression
> > might be useful and help in standarizing errors throughout an application.
> >
> > throw boost:::exception() <<
> > boost::error_info<tag_errorno,tag_filename,tag_size,tag_width>(
> > (1,"output.txt",100,200);
>
> >> Could you clarify what you mean?
>
> Well, I could do something like this:
>
> typedef boost::error_info<tag_errorno,
> tag_filename,tag_size,tag_width> error_t;
>
> throw error_t(1,"output.txt",100,200);

You probably mean:

throw my_error() << error_t(1,"output.txt",100,200);

In my opinion what you're describing is better accomplished like this:

class my_error: public boost::exception
{
public:
    my_error( int errno, std::string file_name, size_t size, int width )
    {
    (*this) <<
            boost::error_info<tag_errno>(errno) <<
            boost::error_info<tag_file_name>(file_name) <<
            boost::error_info<tag_size>(size) <<
            boost::error_info<tag_width>(width);
    }
};

However in my experience with Boost Exception I've never done that.

Occasionally I've defined a local function that's called within a
given compilation unit, like this:

namespace
{
    void throw_my_error( int errno, std::string file_name, size_t
size, int width )
    {
        throw my_error() <<
                boost::error_info<tag_errno>(errno) <<
                boost::error_info<tag_file_name>(file_name) <<
                boost::error_info<tag_size>(size) <<
                boost::error_info<tag_width>(width);
    }
}

I think it is a mistake to standardize globally on the info you want
to stuff into the exception at the time of the throw. What if you
detect an error condition that matches the my_error semantics
completely, yet you don't have a file name to pass to its constructor?
You'd find a way to make the file name available to the throw site,
right?

Instead, Boost Exception allows you to just throw my_error(), even
though you don't have all info needed to handle it; such info can be
added later on, as the exception bubbles up to a context where it is
available naturally.

Similarly, what if you are throwing my_error, but you have additional
info that is relevant to the failure? Sure, you could modify the
my_error definition to add another constructor, but that's an overkill
-- not to mention undesirable because it may force a lot of files to
recompile.

When I use Boost Exception, the two things I care about are:

* Define clear semantics for each exception type
* Correctly classify the failure (derive the appropriate bases.)

Other than that, all of my exception classes look very much the same:
they're empty.

This could go into a "best practices" section in the documentation, if
we agree that this really is the best approach.

Emil Dotchevski


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk