template <class T>
inline Future<T> SemiFuture<T>::via(Executor* executor, int8_t priority) && {
throwIfInvalid();
+ if (!executor) {
+ throwNoExecutor();
+ }
// If current executor is deferred, boost block to ensure that work
// progresses and is run on the new executor.
throw PredicateDoesNotObtain();
}
-[[noreturn]] void throwNoFutureInSplitter() {
- throw NoFutureInSplitter();
+[[noreturn]] void throwNoFutureInSplitter() { throw NoFutureInSplitter(); }
+
+ [[noreturn]] void throwNoExecutor() {
+ throw NoExecutor();
}
} // namespace folly
public:
NoTimekeeper() : FutureException("No timekeeper available") {}
};
+
+[[noreturn]] void throwNoExecutor();
+
+class FOLLY_EXPORT NoExecutor : public FutureException {
+ public:
+ NoExecutor() : FutureException("No executor provided to via") {}
+};
} // namespace folly
makeSemiFuture().value();
}
+TEST(SemiFuture, ViaThrowOnNull) {
+ EXPECT_THROW(makeSemiFuture().via(nullptr), NoExecutor);
+}
+
TEST(SemiFuture, ConstructSemiFutureFromEmptyFuture) {
auto f = SemiFuture<int>{Future<int>::makeEmpty()};
EXPECT_THROW(f.isReady(), NoState);