Naios / continuable

C++14 asynchronous allocation aware futures (supporting then, exception handling, coroutines and connections)
https://naios.github.io/continuable/
MIT License
815 stars 44 forks source link

Customized error type #41

Open weidonglian opened 3 years ago

weidonglian commented 3 years ago

First I really enjoy this great library and really nice work! It does solve the callback hell with asio. Since we have no coroutine available whatsoever, continuable probably is now the best we can achieve.

  1. Regarding the customized error, i.e. cti::exception_t.
 void operator()(exception_arg_t, exception_t exception) && {
    // Only handle the exception when it is present, otherwise handle it as
    // a cancellation of the control flow.
    // This behaviour is intentionally correct for
    // - `std::exception_ptr`
    // - `std::error_code`
    // - `std::error_condition`
    // which allow to be default constructed and then return false
    // by their corresponding `operator bool()`.
    if (bool(exception)) {

In the callback's excetion_t has to implement operator bool which is not so portable and could be confusing,e.g. absl::Status or our own Error. in absl::Status, it prefers to check by absl::Status::ok(), however, bool(exception) should mean a non-zero error code, i.e. not ok, which we do not want to add an operator bool for absl::Status or our own error type.

I am suggesting if we could provide a functor to replace bool(exception), i.e. something similar to std::hash, then we could implement it for the given error type.

  1. Since there is only one definition of cti::exception_t, if we decide to go with our own or google's absl::Status, then the asio's integration will be a problem where only exception_ptr and error_condition are supported. Somehow, we need to map the error_condition into our own error type, e.g. map e.Value() + e.Category() into absl::Status. Then we need to change the continuable's source code? What is the best pattern to deal with it? Is there any considerable support in the future for your library? I know it is probably out of the scope of this library. I am really interested in this library and really would like to use it for our project. Possible solution in the external/asio.hpp:
    promise.set_exception(exception_t(e.value(), e.category()));

    How about template specialization for a different type of exception_t? we can default to std::error_condtion. Then we got a chance to specialize an exception_t on our own, e.g. make_error(e). It would look like:

promise.set_exception(make_error(e));
Naios commented 3 years ago

Sorry that I'm answering late. I don't get notified for arbitrary issues in this reposity unless I get notified (which is explicitly said in the issue template you deleted).

I'm glad that you like the library. I think the best solution is a trait that can be specialized by the user for specific types:

namespace cti {
template<typename T>
struct exception_trait {
  static bool is_exception(T const& value) noexcept {
    return bool(value);
  }

  // ... Possible additional specializations
};
}

I'm open for accepting a pull request that implements this specialization.