[haiku-development] Re: Error Handling (was: Re: Plan for NetServices Kit (v2))

  • From: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Fri, 3 Sep 2021 15:36:12 +1200

On Thu, 2 Sept 2021 at 06:54, Niels Sascha Reedijk <niels.reedijk@xxxxxxxxx>
wrote:

Hi,

I decided to split this into a separate thread.

On Wed, Sep 1, 2021 at 3:41 PM Mr. waddlesplash <waddlesplash@xxxxxxxxx>
wrote:

On Wed, Sep 1, 2021 at 2:32 AM Niels Sascha Reedijk
<niels.reedijk@xxxxxxxxx> wrote:
 Also agreed. Having said that, unless the final decision is to stay
with the legacy error handling without exceptions and using status_t and
invalid objects, it seems likely that we will end up in a situation where
there would be legacy error handling (in the older kits) and modern error
handling (in newer kits).

I think it is worth noting at this point that the major error handling
paradigms of newer languages, like Rust, are pretty much
exception-free (I guess Rust has "recoverable panics" but they are not
at all intended to be used like exceptions), and instead have error
handling strategies that are functionally like status_t returns but
with more syntactic sugar attached.

I think this might be one of the more contentious topics, and I
actually expected your opinion to be more widely shared, which is why
I introduced the Expected<T, E> return type which is modeled after the
std::expected proposal [1] for standard C++. This type comes very
close to Rust's Result<T, E> type.

Having said that... I am not against exceptions, but I do think it is
a feature that needs to have some very clear rules about how and when
they are used in the public API.

The main arguments against exceptions are:
(1) discoverability: there is no inherent language feature that makes
you make exceptions discoverable, so you would have to resort to
documentation or practises that keep the definition of exceptions and
where they can occur close together.
(2) speed: stack unwinding is expensive.
(3) safety: there are challenges writing code that cleanly handles
exceptions

I don't think error codes are necessarily much better.

(1) In terms of discoverability, you could say that when a
function/method returns an error code, it does signal that an error
may occur. However, our convention is to use the `status_t` type, and
we often forward error codes that may have occurred several calls down
from the API call that the user uses. Thus in reality, the potential
clarity of the error code is not much better. In fact, I would argue
that there is no difference between the discoverability of an error
code path between a function that explicitly returns a `status_t` or a
function that is not decorated with `noexcept`. Both can fail!

(2) The cost of exceptions is relative, we no longer live in the 90s
and we have a lot more resources now. Plus, adding checks for if
(status != B_OK) might be cheaper but it is not free.

(3) Modern C++ allows you to do a lot more with scoped objects. If
RAII principles are adhered to, that means that you can write
exception safe code that will not put objects in an inconsistent state
or will leak memory.


Personally, I would prefer that we not use exceptions. I think inventing
our own equivalent to the proposed std::expected is fine. In this case, I
would kind of prefer Expected to return a status_t as the error part.

I also think that we should be looking at adding a whole bunch of
kit-specific errors to status_t. Things B_HTTP_INTERNAL_SERVER_ERROR and
friends. We could probably add various types of helpers for error codes,
like `is_http_error()`, `is_posix_error()`, and so forth. I guess in some
ways, this would be similar to sub-classing exceptions... but at least with
a status_t, or a BExpected<T, status_t> in the API, users of the API can
know to expect an error is possible.

One of the nicer things about the Windows API is that they have a whole
bunch of very specific error codes (and heck, they even use error values
that look the same as what Haiku uses). When pkgman returns crap like
B_INTERRUPTED, it's of no value to anybody--gee, thanks, I know what that
means...

Other related posts: