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

Failed assertion when giving make_exceptional_continuable() to when_seq() #50

Open rkonklewski-am2m opened 1 year ago

rkonklewski-am2m commented 1 year ago

Hi, @Naios!

It seems I found another issue: when_seq() connection operator can't deal with ready exceptional continuables (i.e. created by make_exceptional_continuable()). It doesn't have the same problem with lazy exceptional continuables. Moreover, when_all() and when_any() operators don't have the problem at all. Neither does the chaining operator (>>).

To me this is a corner case and not a high priority. A workaround is to chain something to ready continuables before giving them to when_seq() (see Steps to Reproduce).


Commit Hash

4.2.0 release

Expected Behavior

when_seq() forwards the exception like it would for a lazy exceptional continuable.

Actual Behavior

Assertion failed: is_value(), file *redacted*\continuable\include\continuable/detail/utility/result-variant.hpp, line 167

Steps to Reproduce

auto eptr = std::make_exception_ptr(std::exception("test"));
// case 1: lazy exceptional continuable is fine
cti::when_seq(cti::async([eptr]() -> int { std::rethrow_exception(eptr); }));
// case 2: ready exceptional continuable triggers an assertion failure
cti::when_seq(cti::make_exceptional_continuable<int>(eptr));
// case 3: chaining something to a ready exceptional continuable fixes the issue
cti::when_seq(cti::make_exceptional_continuable<int>(eptr).then([](auto) {}));

Your Environment

Naios commented 1 year ago

Thanks for your report, all chaining operations are optimized for ready continuables and probably the issue originates from there. I will take a closer look into it. when_all and when_any use a different traversal code than when_seq so it's reasaonable that these operations are not affected by this bug.