mirror of
https://github.com/Naios/continuable.git
synced 2026-01-01 03:12:12 +08:00
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:
parent
ed8310e345
commit
18e644045f
@ -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<>{});
|
||||
|
||||
@ -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);
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user