You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2021/10/03 12:10:29 UTC

[celix] branch master updated: Fixing slicing of exception in Promise

This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/celix.git


The following commit(s) were added to refs/heads/master by this push:
     new 4eb6c1f  Fixing slicing of exception in Promise<void>
     new 7250126  Merge pull request #368 from stegemr/feature/fixVoidPromiseExceptions
4eb6c1f is described below

commit 4eb6c1fe7f9e47d91b16b09fe6c6069eb5e4a3c1
Author: stegemanr <st...@gmail.com>
AuthorDate: Wed Sep 29 08:58:52 2021 +0200

    Fixing slicing of exception in Promise<void>
---
 libs/promises/api/celix/Deferred.h               |  8 ++-
 libs/promises/gtest/src/VoidPromisesTestSuite.cc | 75 ++++++++++++++++++++++++
 2 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/libs/promises/api/celix/Deferred.h b/libs/promises/api/celix/Deferred.h
index 03cfc9f..bf8f1ff 100644
--- a/libs/promises/api/celix/Deferred.h
+++ b/libs/promises/api/celix/Deferred.h
@@ -168,7 +168,8 @@ namespace celix {
          * @param failure The failure in the form of an const std::exception reference.
          * @throws PromiseInvocationException If the associated Promise was already resolved.
          */
-        void fail(const std::exception& failure);
+        template<typename E, typename std::enable_if_t< std::is_base_of<std::exception, E>::value, bool> = true >
+        void fail(const E& failure);
 
         /**
          * Returns the Promise associated with this Deferred.
@@ -227,8 +228,9 @@ void celix::Deferred<T>::fail(const E& failure) {
     state->template fail<E>(failure);
 }
 
-inline void celix::Deferred<void>::fail(const std::exception& failure) {
-    state->fail(failure);
+template<typename E, typename std::enable_if_t< std::is_base_of<std::exception, E>::value, bool>>
+inline void celix::Deferred<void>::fail(const E& failure) {
+    state->template fail<E>(failure);
 }
 
 template<typename T>
diff --git a/libs/promises/gtest/src/VoidPromisesTestSuite.cc b/libs/promises/gtest/src/VoidPromisesTestSuite.cc
index f2efdb5..9accd54 100644
--- a/libs/promises/gtest/src/VoidPromisesTestSuite.cc
+++ b/libs/promises/gtest/src/VoidPromisesTestSuite.cc
@@ -126,6 +126,81 @@ TEST_F(VoidPromiseTestSuite, onFailureHandling) {
     EXPECT_EQ(true, resolveCalled);
 }
 
+TEST_F(VoidPromiseTestSuite, onFailureHandlingLogicError) {
+    auto deferred =  factory->deferred<void>();
+    std::atomic<bool> successCalled = false;
+    std::atomic<bool> failureCalled = false;
+    std::atomic<bool> resolveCalled = false;
+    auto p = deferred.getPromise()
+            .onSuccess([&]() {
+                successCalled = true;
+            })
+            .onFailure([&](const std::exception &e) {
+                failureCalled = true;
+                ASSERT_TRUE(0 == strcmp("Some Exception",  e.what())) << std::string(e.what());
+            })
+            .onResolve([&]() {
+                resolveCalled = true;
+            });
+
+    deferred.fail(std::logic_error("Some Exception"));
+
+    factory->wait();
+    EXPECT_EQ(false, successCalled);
+    EXPECT_EQ(true, failureCalled);
+    EXPECT_EQ(true, resolveCalled);
+}
+
+TEST_F(VoidPromiseTestSuite, onFailureHandlingPromiseIllegalStateException) {
+    auto deferred =  factory->deferred<void>();
+    std::atomic<bool> successCalled = false;
+    std::atomic<bool> failureCalled = false;
+    std::atomic<bool> resolveCalled = false;
+    auto p = deferred.getPromise()
+            .onSuccess([&]() {
+                successCalled = true;
+            })
+            .onFailure([&](const std::exception &e) {
+                failureCalled = true;
+                ASSERT_TRUE(0 == strcmp("Illegal state",  e.what())) << std::string(e.what());
+            })
+            .onResolve([&]() {
+                resolveCalled = true;
+            });
+
+    deferred.fail(celix::PromiseIllegalStateException());
+
+    factory->wait();
+    EXPECT_EQ(false, successCalled);
+    EXPECT_EQ(true, failureCalled);
+    EXPECT_EQ(true, resolveCalled);
+}
+
+TEST_F(VoidPromiseTestSuite, onFailureHandlingPromiseInvocationException) {
+    auto deferred =  factory->deferred<void>();
+    std::atomic<bool> successCalled = false;
+    std::atomic<bool> failureCalled = false;
+    std::atomic<bool> resolveCalled = false;
+    auto p = deferred.getPromise()
+            .onSuccess([&]() {
+                successCalled = true;
+            })
+            .onFailure([&](const std::exception &e) {
+                failureCalled = true;
+                ASSERT_TRUE(0 == strcmp("MyExceptionText",  e.what())) << std::string(e.what());
+            })
+            .onResolve([&]() {
+                resolveCalled = true;
+            });
+
+    deferred.fail(celix::PromiseInvocationException("MyExceptionText"));
+
+    factory->wait();
+    EXPECT_EQ(false, successCalled);
+    EXPECT_EQ(true, failureCalled);
+    EXPECT_EQ(true, resolveCalled);
+}
+
 TEST_F(VoidPromiseTestSuite, resolveSuccessWith) {
     auto deferred1 = factory->deferred<void>();
     bool called = false;