typedef typename FirstArgOf<F>::type::value_type Result;
folly::Try<Result> result;
+ std::exception_ptr funcException;
Baton baton;
- baton.wait([&func, &result, &baton]() mutable {
- func(Promise<Result>(result, baton));
+ baton.wait([&func, &result, &baton, &funcException]() mutable {
+ try {
+ func(Promise<Result>(result, baton));
+ } catch (...) {
+ // Save the exception, but still wait for baton to be posted by user code
+ // or promise destructor.
+ funcException = std::current_exception();
+ }
});
+ if (UNLIKELY(funcException != nullptr)) {
+ std::rethrow_exception(funcException);
+ }
+
return folly::moveFromTry(result);
}
}
loopController.loop(std::move(loopFunc));
}
+TEST(FiberManager, awaitThrow) {
+ folly::EventBase evb;
+ struct ExpectedException {};
+ getFiberManager(evb)
+ .addTaskFuture([&] {
+ EXPECT_THROW(
+ await([](Promise<int> p) {
+ p.setValue(42);
+ throw ExpectedException();
+ }),
+ ExpectedException
+ );
+
+ EXPECT_THROW(
+ await([&](Promise<int> p) {
+ evb.runInEventBaseThread([p = std::move(p)]() mutable {
+ p.setValue(42);
+ });
+ throw ExpectedException();
+ }),
+ ExpectedException);
+ })
+ .waitVia(&evb);
+}
+
TEST(FiberManager, addTasksThrow) {
std::vector<Promise<int>> pendingFibers;
bool taskAdded = false;