|
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