mirror of
https://github.com/Naios/continuable.git
synced 2026-02-09 11:16:40 +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)...);
|
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>
|
template <typename T, typename... Args>
|
||||||
constexpr auto make_invoker(T&& invoke, identity<Args...>) {
|
constexpr auto make_invoker(T&& invoke, identity<Args...>) {
|
||||||
return invoker<std::decay_t<T>, identity<Args...>>(std::forward<T>(invoke));
|
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
|
CONTINUABLE_BLOCK_TRY_BEGIN
|
||||||
invoke_callback(std::forward<decltype(callback)>(callback),
|
invoke_callback(std::forward<decltype(callback)>(callback),
|
||||||
std::forward<decltype(args)>(args)...);
|
std::forward<decltype(args)>(args)...);
|
||||||
invoke_void_no_except(
|
|
||||||
identity<traits::unrefcv_t<decltype(args)>...>{},
|
invoke_no_except(std::forward<decltype(next_callback)>(next_callback));
|
||||||
std::forward<decltype(next_callback)>(next_callback));
|
|
||||||
CONTINUABLE_BLOCK_TRY_END
|
CONTINUABLE_BLOCK_TRY_END
|
||||||
},
|
},
|
||||||
identity<>{});
|
identity<>{});
|
||||||
|
|||||||
@ -194,3 +194,15 @@ TYPED_TEST(single_dimension_tests, token_remap_ignore) {
|
|||||||
|
|
||||||
ASSERT_TRUE(value.is_value());
|
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());
|
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 handled = std::make_shared<bool>(false);
|
||||||
auto continuation = this->supply_exception(supply_test_exception())
|
auto continuation = this->supply_exception(supply_test_exception())
|
||||||
.fail([handled](cti::exception_t) {
|
.fail([handled](cti::exception_t) {
|
||||||
@ -47,10 +47,23 @@ TYPED_TEST(single_dimension_tests, are_never_completed_after_error_handled) {
|
|||||||
*handled = true;
|
*handled = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
ASSERT_ASYNC_INCOMPLETION(std::move(continuation));
|
ASSERT_ASYNC_COMPLETION(std::move(continuation));
|
||||||
ASSERT_TRUE(*handled);
|
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) {
|
TYPED_TEST(single_dimension_tests, fail_is_accepting_plain_continuables) {
|
||||||
auto handled = std::make_shared<bool>(false);
|
auto handled = std::make_shared<bool>(false);
|
||||||
auto handler = this->supply().then([handled] {
|
auto handler = this->supply().then([handled] {
|
||||||
@ -61,7 +74,7 @@ TYPED_TEST(single_dimension_tests, fail_is_accepting_plain_continuables) {
|
|||||||
auto continuation =
|
auto continuation =
|
||||||
this->supply_exception(supply_test_exception()).fail(std::move(handler));
|
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);
|
ASSERT_TRUE(*handled);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,13 +122,13 @@ TYPED_TEST(single_dimension_tests, are_flow_error_accepting) {
|
|||||||
*handled = true;
|
*handled = true;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
ASSERT_ASYNC_INCOMPLETION(std::move(continuation));
|
ASSERT_ASYNC_COMPLETION(std::move(continuation));
|
||||||
ASSERT_TRUE(*handled);
|
ASSERT_TRUE(*handled);
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPED_TEST(single_dimension_tests, are_exceptions_partial_applyable) {
|
TYPED_TEST(single_dimension_tests, are_exceptions_partial_applyable) {
|
||||||
bool handled = false;
|
bool handled = false;
|
||||||
ASSERT_ASYNC_INCOMPLETION(
|
ASSERT_ASYNC_COMPLETION(
|
||||||
this->supply_exception(supply_test_exception()).fail([&]() -> void {
|
this->supply_exception(supply_test_exception()).fail([&]() -> void {
|
||||||
EXPECT_FALSE(handled);
|
EXPECT_FALSE(handled);
|
||||||
handled = true;
|
handled = true;
|
||||||
|
|||||||
@ -170,10 +170,12 @@ TYPED_TEST(single_dimension_tests, multipath_exception_is_continuable) {
|
|||||||
|
|
||||||
TYPED_TEST(single_dimension_tests, multipath_exception_is_autocanceled) {
|
TYPED_TEST(single_dimension_tests, multipath_exception_is_autocanceled) {
|
||||||
bool caught = false;
|
bool caught = false;
|
||||||
ASSERT_ASYNC_INCOMPLETION(
|
ASSERT_ASYNC_COMPLETION(
|
||||||
this->supply_exception(supply_test_exception()).fail([&](exception_t) {
|
this->supply_exception(supply_test_exception()).fail([&](exception_t) {
|
||||||
EXPECT_FALSE(caught);
|
EXPECT_FALSE(caught);
|
||||||
caught = true;
|
caught = true;
|
||||||
|
}).fail([](exception_t){
|
||||||
|
FAIL();
|
||||||
}));
|
}));
|
||||||
ASSERT_TRUE(caught);
|
ASSERT_TRUE(caught);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user