Boost logo

Boost :

Subject: Re: [boost] [system] Would it be possible to trial a breaking change to Boost.System and see what happens?
From: Richard Hodges (hodges.r_at_[hidden])
Date: 2018-01-15 09:25:43


My 2c...

Almost all the asio client code I have written in the past 4 years uses
handlers like this:

async_xxx(xxx, [self = this->shared_from_this()](auto&& ec)
{
  if (ec) {
    self->xxx_error(ec);
  }
  else {
    self->please_carry_on();
  }
});

Because it seemed logically obvious that ec would be true if it contained
an error. I did once notice that when writing my own boost::system category
that a zero error code broke this, so made a mental note to avoid zero
error codes in custom error schemes (e.g. rpc_error, database_error,
message_bus_error etc.)

So for my part, although I loathe the idea of changing interfaces, this
interface seems broken and probably could do with being changed. Perhaps
there should be a category of errors which is std::success and another
std::success_with_warning? In this way, NT error codes could be propagated
more accurately.

Re outcome, I was a sceptic to being with (why would be wrap a variant<X,
error_code>?) but now I see that it's preferable. Ideally there should be
no system_error indicating success at all. That would ensure more robust
logical handling of errors in all cases.

I eagerly await the release of boost.outcome. I plan to retro-fit it into
all my custom asio services. I am sure it will expose a number of subtle
bugs.

R

On 15 January 2018 at 04:54, Gavin Lambert via Boost <boost_at_[hidden]>
wrote:

> On 14/01/2018 18:02, Peter Dimov wrote:
>
>> `f` should not need to know what errors are being returned by `do_f1`,
>> `do_f2`, `do_f3`, in order to check whether the calls succeeded; the whole
>> point of using error_code is that errors from different domains can be
>> handled in a generic manner.
>>
>> This is similar to exceptions; `f` needs not know what callees can throw.
>> Today, `do_f1` is implemented with backend A, so it throws A-flavored
>> exceptions; tomorrow, it switches to backend B and throws B-flavored
>> exceptions. The logic in `f` doesn't change.
>>
>> In the same way, whether `do_f1` returns error codes of category A or
>> category B should not matter for the logic in `f`. There must exist a
>> generic way to test for failure. If !ec is not it, well, then !ec shouldn't
>> be used and we need something that is and should be.
>>
>
> I think Christopher's assertion works in a world where error_codes are
> never blindly propagated upwards; regardless of whether library X uses
> library A or library B under the hood, it must only return standard errors
> or library X errors to its external callers, never library A or B errors.
> (It's up to the library itself when to do the conversion, but it usually
> makes the most sense to do it as soon as possible.)
>
> I think the general consensus from the Outcome discussion was that this is
> not the desired practice and that error_codes are indeed supposed to be
> propagated unmodified for the most part.
>
> I haven't quite worked out yet where I stand on that; I think I'd prefer
> if the error codes were converted but it was still possible to obtain a
> "history" of an error, somewhat like nested exceptions. But I also
> recognise that that could have significant performance drawbacks.
>
>
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman
> /listinfo.cgi/boost
>


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