Boost logo

Boost :

Subject: Re: [boost] [system][filesystem v3] Question about error_code arguments
From: Stewart, Robert (Robert.Stewart_at_[hidden])
Date: 2009-11-02 08:53:35


Detlef Vollmann wrote:
> Stewart, Robert wrote:
> > Detlef Vollmann wrote:
> >> Stewart, Robert wrote:
> >>> >From a debugging perspective, the exception will be thrown
> >>>> at the wrong point.
> >> What you would probably throw is not the original exception,
> >> but an exception objects of some type like 'unhandled_error'
> >> that has inside the original exception data.
> >
> > That's fine, but then an exception isn't thrown at the
> > point where the error was detected, so the stack frame giving
> > context for the error is lost.
>
> From a pedantic point of view I could argue that the exception
> is that the error wasn't handled, and the context of that exception
> would be preserved. But I admit that the really interesting thing
> is where the original error occurred, and that is lost.

In this case, the developer indicated non-throwing error handling and then didn't manage that correctly. Until that's addressed, the rest is less important; once addressed, the rest will probably be correct (due to the addition of error handling code). Consequently, my debugging argument is weak.

> >> For a lot of system level calls, you could get quite a number
> >> of different error codes. Some of them are not really exceptional
> >> errors (e.g. EAGAIN) in a lot of contexts. But it's up to
> >> the application what error codes represent exceptional
> >> errors and which don't.
> >
> > That's an interesting notion. I'm sure those in this
> > discussion that want exceptions in all cases would expect
> > different exception types to represent some of the types of
> > errors that can occur. Your approach will collapse them into
> > a single type.
>
> Separate exception objects are the old times.

If you say so.

> Now we have exceptions like regex_error, future_error or system_error,
> whose sole purpose is to wrap a lot of different errors into one
> exception.

Those are design choices of certain libraries. That doesn't make the choices ubiquitous.

> >> So the call would be something like
> >> 'device.read(error_object, ...)'
> >> and error_object would have member functions to query for
> >> error codes,
> >> and the destructor would throw, if error_object would
> >> contain an error
> >> code that was not queried for.
> >
> > One must check for each possible error individually in
> > order to avoid an exception? That doesn't seem beneficial.
>
> There are many cases in which one wants to check for specific
> errors to handle locally and to throw an exception for the
> rest or just return a failure indication -- perhaps after
> logging the problem. Thus, there should be a means to simply
> query generally for failure and have that prevent throwing an
> exception.

You are mixing the two approaches that have been proposed thus far. Thus far, the idea has been to either throw an exception or deal with error codes. Thus, for your scenario, you must inspect the error_code object for errors. If you want exceptions, you must throw them in your code. If you fail to check for errors, the error_code object *might* be able to throw an exception to alert you to that programming error.

> The idea is that you check for things that are not
> exceptional, and for everything else an error is thrown.

This is a new idea to this thread and I find it unwise.

> > Ideally, what we want is a compile-time failure if the
> > error_code isn't checked. After all, the point is that we
> > nt to be sure that the caller gets an exception or checks
> for failure.
>
> No, only non-exceptional "errors" should be checked, all others throw
> an exception.

This is based upon your newly suggested idea. Given the basis of the previous discussion of this mechanism, a compile time failure would work fine, if it were possible.

> Especially in system level code, it's really the application that
> defines what errors are exceptional and what "errors" are to be
> expected.

Exactly. Hence, application level code must inspect the error_code object to determine what occurred and decide whether to throw an exception. The application code must not check for some errors and then assume the error_code will throw some useful exception for the rest.

As has been covered in this thread, one cannot count on a destructor throwing an exception when wanted and otherwise not. It is, therefore, unwise to design the mechanism on that foundation.

> > ~error_code() could test for a pending exception before
> > throwing an exception. If there is a pending exception, that
> > means the stack is being unwound and the error_code shouldn't
> > aggravate the situation by throwing its own. Otherwise, it
> > can throw in its destructor, right?
>
> In theory, yes. But that would violate a lot of exception safety
> guarantees.

Your notion of ~error_code() throwing an exception if one doesn't check for the actual error that occurred does the same.

_____
Rob Stewart robert.stewart_at_[hidden]
Software Engineer, Core Software using std::disclaimer;
Susquehanna International Group, LLP http://www.sig.com

IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.


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