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;