From 6c209c876a4a10614c07a3e78c8ff5b9a2682b66 Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Thu, 25 Jan 2018 05:21:13 +0100 Subject: [PATCH] Allows fail to accept plain continuables --- include/continuable/continuable-base.hpp | 25 ++++++++++++++++++- .../test-continuable-base-errors.cpp | 14 +++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/include/continuable/continuable-base.hpp b/include/continuable/continuable-base.hpp index 475f87a..9da4c64 100644 --- a/include/continuable/continuable-base.hpp +++ b/include/continuable/continuable-base.hpp @@ -262,7 +262,7 @@ public: /// the callback. See the description in `then` above. /// /// \returns Returns a continuable_base with an asynchronous return type - /// depending on the current result type. + /// depending on the previous result type. /// /// /// \since version 2.0.0 @@ -275,6 +275,29 @@ public: std::forward(executor)); } + /// Additional overload of the continuable_base::fail() method + /// which is accepting a continuable_base itself. + /// + /// \param continuation A continuable_base reflecting the continuation + /// which is used to continue the call hierarchy on errors. + /// The result of the current continuable is discarded and the given + /// continuation is invoked as shown below. + /// ```cpp + /// http_request("github.com") + /// .fail(http_request("atom.io")) + /// ``` + /// + /// \returns Returns a continuable_base with an asynchronous return type + /// depending on the previous result type. + /// + /// \since version 2.0.0 + template + auto fail(continuable_base&& continuation) && { + continuation.freeze(); + return std::move(*this).fail([continuation = std::move(continuation)]( + detail::types::error_type) mutable { std::move(continuation).done(); }); + } + /// A method which allows to use an overloaded callable for the error /// as well as the valid result path. /// diff --git a/test/unit-test/test-continuable-base-errors.cpp b/test/unit-test/test-continuable-base-errors.cpp index ff47196..573dad9 100644 --- a/test/unit-test/test-continuable-base-errors.cpp +++ b/test/unit-test/test-continuable-base-errors.cpp @@ -49,6 +49,20 @@ TYPED_TEST(single_dimension_tests, are_never_completed_after_error_handled) { ASSERT_TRUE(*handled); } +TYPED_TEST(single_dimension_tests, fail_is_accepting_plain_continuables) { + auto handled = std::make_shared(false); + auto handler = this->supply().then([handled] { + ASSERT_FALSE(*handled); + *handled = true; + }); + + auto continuation = + this->supply_exception(supply_test_exception()).fail(std::move(handler)); + + ASSERT_ASYNC_INCOMPLETION(std::move(continuation)); + ASSERT_TRUE(*handled); +} + #if !defined(CONTINUABLE_WITH_NO_EXCEPTIONS) // Enable this test only if we support exceptions TYPED_TEST(single_dimension_tests, are_yielding_errors_from_handlers) {