Boost logo

Boost :

From: Beman Dawes (bdawes_at_[hidden])
Date: 2006-05-23 16:31:46


"Christopher Kohlhoff" <chris_at_[hidden]> wrote in message
news:20060522134258.91630.qmail_at_web32609.mail.mud.yahoo.com...
> Hello all,
>
> I have been thinking about how to reconcile Boost.Asio error
> handling with the system error classes defined in the TR2
> filesystem proposal N1975. I have some concerns which I'll
> outline in the context of how I plan to use them.
>
> The current plan is as follows:
>
> - Synchronous functions would by default throw a system_error
> exception.
>
> - An overload of each synchronous function would take an
> error_code& as the final argument. On failure these functions
> set the error_code to the appropriate error. On success, the
> error_code is set to represent the no error state. These
> functions do not throw exceptions.

So far, so good.

> - Callback handlers for asynchronous functions would take an
> error_code as the first parameter. For example:
>
> void handle_read(error_code ec)
> {
> ...
> }

That makes sense to me. It wouldn't be useful to throw an exception because
of the asynchronous nature of the control flow, so supplying a error_code to
the callback gives it a chance to deal with the error, or ignore it if
desired. Was that your analysis?

> - Since many error codes in socket programming are "well-known"
> and often tested for explicitly, they need to be defined
> somewhere. The current errors in the asio::error::code_type
> enum would be replaced by constants of type error_code:
>
> namespace boost {
> namespace asio {
> namespace error {
>
> const error_code access_denied = implementation_defined;
> const error_code message_size = implementation_defined;
> ...
>
> } // namespace error
> } // namespace asio
> } // namespace boost
>
> (Note that in practice boost::asio::error might actually be a
> class with static members rather than a namespace).
>
> The issues I have run into so far are:
>
> - The error_code class seems to assume that there is a single
> "namespace" for the system_error_type values. This is not
> necessarily the case for the errors in socket programming.
>
> For example on UNIX most socket functions use errno values,
> but the netdb functions (gethostbyname and friends) use a
> different set of error values starting from 1, and the
> getaddrinfo/getnameinfo functions use another set of error
> values starting from 1.
>
> Would it be possible for the error_code class to have a
> category value (which is probably an integer with
> implementation-defined values) to allow the creation of unique
> error_code values for each type of system error? A category
> value would also allow implementors and users to extend the
> system error classes for other sources of system error (e.g.
> SSL errors, application-specific errors, etc).

I haven't thought of the case of several "namespaces" or "errorspaces"
before, so please take what follows as an initial idea, not something cast
in concrete.

My initial thought is to leave error_code alone, since it should be fine for
most uses. For uses that need more information, such as asio, derive
asio_error_code from error_code, adding appropriate members. For example,
members to set/get the well known socket error codes.

That way users who don't care about the domain specific codes can just use
the error_code base member functions, while those that care about the
specific codes can use the derived asio_error_code functions.

Does that seem a bit cleaner than your approach of adding codes? What is
your reaction?

> - A common idiom in code that uses asio, when you don't care
> about a specific error type, is to simply treat the error as a
> bool:
>
> void handle_read(asio::error e)
> {
> if (e)
> {
> // take action because of error
> }
> else
> {
> // success
> }
> }
>
> Can the error_code class be made convertible-to-bool and also
> have operator! to support this style?

Yes, something like that would be very useful. I just made that mistake
(forgetting the error() function and assuming convetibility to bool) this
morning. The resulting error messages were classics of misdirection - they
went on about shared_ptr, of all things, not instantiating correctly! Took
me ten minutes to figure out the real problem.

So, yes. IIRC, there has been prior list discussion of the best way to
provide convertibility to bool. I'll google around and see if I can find it.
If anyone else remembers the discussion, please feel free to provide a
pointer or a summary.

> - Are these classes available in CVS somewhere so they can be
> reused by other boost libraries?

No. I was waiting for 1.34 to ship, but that is taking a long time so I'll
go ahead and update CVS head, hopefully tomorrow.

Thanks for trying the error_code approach with asio!

--Beman


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