Recover continuable after invoking void fail handlers, s.t. continuable after void fail handlers invoked can be wait. Solve second case of issue #46.

This commit is contained in:
Yuan Yao 2022-05-19 22:01:49 +08:00
parent ed8310e345
commit 18e644045f
4 changed files with 35 additions and 19 deletions

View File

@ -293,16 +293,6 @@ constexpr void invoke_no_except(T&& callable, Args&&... args) noexcept {
std::forward<T>(callable)(std::forward<Args>(args)...);
}
template <typename... Args, typename T>
void invoke_void_no_except(identity<exception_arg_t, Args...>,
T&& /*callable*/) noexcept {
// Don't invoke the next failure handler when being in an exception handler
}
template <typename... Args, typename T>
void invoke_void_no_except(identity<Args...>, T&& callable) noexcept {
std::forward<T>(callable)();
}
template <typename T, typename... Args>
constexpr auto make_invoker(T&& invoke, identity<Args...>) {
return invoker<std::decay_t<T>, identity<Args...>>(std::forward<T>(invoke));
@ -373,9 +363,8 @@ inline auto invoker_of(identity<void>) {
CONTINUABLE_BLOCK_TRY_BEGIN
invoke_callback(std::forward<decltype(callback)>(callback),
std::forward<decltype(args)>(args)...);
invoke_void_no_except(
identity<traits::unrefcv_t<decltype(args)>...>{},
std::forward<decltype(next_callback)>(next_callback));
invoke_no_except(std::forward<decltype(next_callback)>(next_callback));
CONTINUABLE_BLOCK_TRY_END
},
identity<>{});

View File

@ -194,3 +194,15 @@ TYPED_TEST(single_dimension_tests, token_remap_ignore) {
ASSERT_TRUE(value.is_value());
}
TYPED_TEST(single_dimension_tests, wait_test_issue_46) {
bool handled = false;
make_exceptional_continuable<void>(supply_test_exception())
.fail([&]{
EXPECT_FALSE(handled);
handled = true;
})
.apply(cti::transforms::wait());
ASSERT_TRUE(handled);
}

View File

@ -39,7 +39,7 @@ TYPED_TEST(single_dimension_tests, are_yielding_error_result) {
get_test_exception_proto());
}
TYPED_TEST(single_dimension_tests, are_never_completed_after_error_handled) {
TYPED_TEST(single_dimension_tests, are_completed_after_error_handled) {
auto handled = std::make_shared<bool>(false);
auto continuation = this->supply_exception(supply_test_exception())
.fail([handled](cti::exception_t) {
@ -47,10 +47,23 @@ TYPED_TEST(single_dimension_tests, are_never_completed_after_error_handled) {
*handled = true;
});
ASSERT_ASYNC_INCOMPLETION(std::move(continuation));
ASSERT_ASYNC_COMPLETION(std::move(continuation));
ASSERT_TRUE(*handled);
}
TYPED_TEST(single_dimension_tests, are_recoverable_after_error_handled) {
auto recovered = std::make_shared<bool>(false);
auto continuation = this->supply_exception(supply_test_exception())
.fail([](cti::exception_t){})
.then([recovered]{
ASSERT_FALSE(*recovered);
*recovered = true;
});
ASSERT_ASYNC_COMPLETION(std::move(continuation));
ASSERT_TRUE(*recovered);
}
TYPED_TEST(single_dimension_tests, fail_is_accepting_plain_continuables) {
auto handled = std::make_shared<bool>(false);
auto handler = this->supply().then([handled] {
@ -61,7 +74,7 @@ TYPED_TEST(single_dimension_tests, fail_is_accepting_plain_continuables) {
auto continuation =
this->supply_exception(supply_test_exception()).fail(std::move(handler));
ASSERT_ASYNC_INCOMPLETION(std::move(continuation));
ASSERT_ASYNC_COMPLETION(std::move(continuation));
ASSERT_TRUE(*handled);
}
@ -109,13 +122,13 @@ TYPED_TEST(single_dimension_tests, are_flow_error_accepting) {
*handled = true;
}));
ASSERT_ASYNC_INCOMPLETION(std::move(continuation));
ASSERT_ASYNC_COMPLETION(std::move(continuation));
ASSERT_TRUE(*handled);
}
TYPED_TEST(single_dimension_tests, are_exceptions_partial_applyable) {
bool handled = false;
ASSERT_ASYNC_INCOMPLETION(
ASSERT_ASYNC_COMPLETION(
this->supply_exception(supply_test_exception()).fail([&]() -> void {
EXPECT_FALSE(handled);
handled = true;

View File

@ -170,10 +170,12 @@ TYPED_TEST(single_dimension_tests, multipath_exception_is_continuable) {
TYPED_TEST(single_dimension_tests, multipath_exception_is_autocanceled) {
bool caught = false;
ASSERT_ASYNC_INCOMPLETION(
ASSERT_ASYNC_COMPLETION(
this->supply_exception(supply_test_exception()).fail([&](exception_t) {
EXPECT_FALSE(caught);
caught = true;
}).fail([](exception_t){
FAIL();
}));
ASSERT_TRUE(caught);
}