Boost logo

Boost :

From: Jessie Hernandez (jessie_at_[hidden])
Date: 2003-10-30 14:59:33


"Bronek Kozicki" <Brok_at_[hidden]> wrote in message
news:005601c39eec$676ca630$1700000a_at_integral.int...
[snip]
> why don't we just make *small* hierarchy of exceptions, all derived from
> "socket_error" derived from "std::runtime_error" ? I hope that main LWG
> objection was agains large number of exception classes, and I feel that
> 20 might be bit too many. Here "too many" means : it might be difficult
> to define (and use correctly) them, assuming each exception class has
> different meaning.
>
> Another point: currently C++ standard defines only small set of
> exception. I can perfectly understand Committee objections against
> extending this hierarchy with many exception classes, specific to few
> problem domains. Maybe defining namespaces (specifit to these domains)
> inside std namespace, or defining exception classes inside other (domain
> specific) classes could dismiss *some* objections (while rising others),
> that's just my blind guess.
>

I think Bronek's suggestion is the best way to go. I like the current
hierarchy, where you have exception bases, such as connect_failure, which
you can catch if you don't care what specific connect failure it was, or you
can catch the more specific error if you do. I can understand, though, that
there might be too many exception classes. The current hierarchy is as
follows:

runtime_error
    boost::net::socket_base::failure
        boost::net::host_base::failure
            boost::net::host_base::no_address
            boost::net::host_base::no_recovery
            boost::net::host_base::not_found
            boost::net::host_base::try_again
        boost::net::protocol::not_found
        boost::net::service::not_found
        boost::net::socket_base::bind_failure
            boost::net::socket_base::address_protected
            boost::net::socket_base::already_bound
        boost::net::socket_base::connect_failure
            boost::net::socket_base::already_connected
            boost::net::socket_base::connection_refused
            boost::net::socket_base::timed_out
        boost::net::socket_base::create_failure
            boost::net::socket_base::unsupported_domain
            boost::net::socket_base::unsupported_protocol
        boost::net::socket_base::network_unreachable
        boost::net::socket_base::permission_denied

What I can do, as Bronek mentioned, is reduce the amount of classes, and
have what currently are the "base" exceptions have an error code function.
So the hierarchy can be converted to this:

runtime_error
    boost::net::socket_base::failure
        boost::net::host_base::failure
        boost::net::protocol::not_found
        boost::net::service::not_found
        boost::net::socket_base::bind_failure
        boost::net::socket_base::connect_failure
        boost::net::socket_base::create_failure
        boost::net::socket_base::network_unreachable
        boost::net::socket_base::permission_denied

So client code will change from:

try
{
    ...
}
catch( const socket_base::already_bound& e )
{
    ...
}
catch( const socket_base::connection_refused& e )
{
    ...
}

to this:

try
{
    ...
}
catch( const socket_base::bind_failure& e )
{
    if( e.reason() == socket_base::already_bound )
        ...
}
catch( const socket_base::connect_failure& e )
{
    if( e.reason() == socket_base::connection_refused )
        ...
}

The above hierarchy, I think, is the best of both worlds: you have a minimal
number of exception classes covering broad types of errors. Each of these
broad exceptions can be caught, and if desired, the specific error can be
checked with a reason() method that will return the specific type of
failure.

I will be making this change (along with the design document) in my next
release. Let me know if anyone has any objections with the above change.
Thanks.

--
Jessie Hernandez

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