Commit 09c8a80a authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Split Futures exceptions by Promise vs Future

Summary:
[Folly] Split Futures exceptions by `Promise` vs `Future`.

* Move `Promise` exceptions into the `Promise` header.
* Move `Future` exceptions into the `Future` header.
* Split `NoState` into `PromiseInvalid` and `FutureInvalid`.
* Remove the newly-empty exceptions header.

Reviewed By: andriigrynenko

Differential Revision: D7966499

fbshipit-source-id: 2dc6d2a941493979ebf47b3e70e5cf6a6fbd33cf
parent f5063ec7
......@@ -214,7 +214,6 @@ nobase_follyinclude_HEADERS = \
futures/helpers.h \
futures/Future.h \
futures/Future-inl.h \
futures/FutureException.h \
futures/FutureSplitter.h \
futures/Promise-inl.h \
futures/Promise.h \
......
......@@ -235,7 +235,7 @@ void FutureBase<T>::detach() {
template <class T>
void FutureBase<T>::throwIfInvalid() const {
if (!core_) {
throw_exception<NoState>();
throw_exception<FutureInvalid>();
}
}
......@@ -721,7 +721,7 @@ SemiFuture<T>& SemiFuture<T>::operator=(Future<T>&& other) noexcept {
template <class T>
Future<T> SemiFuture<T>::via(Executor* executor, int8_t priority) && {
if (!executor) {
throw_exception<NoExecutor>();
throw_exception<FutureNoExecutor>();
}
if (auto deferredExecutor = getDeferredExecutor()) {
......@@ -1044,7 +1044,7 @@ template <class T>
template <class F>
Future<T> Future<T>::onTimeout(Duration dur, F&& func, Timekeeper* tk) {
return within(dur, tk).onError(
[funcw = std::forward<F>(func)](TimedOut const&) mutable {
[funcw = std::forward<F>(func)](FutureTimeout const&) mutable {
return std::forward<F>(funcw)();
});
}
......@@ -1631,7 +1631,7 @@ Future<T> unorderedReduce(It first, It last, T initial, F func) {
template <class T>
Future<T> Future<T>::within(Duration dur, Timekeeper* tk) {
return within(dur, TimedOut(), tk);
return within(dur, FutureTimeout(), tk);
}
template <class T>
......@@ -1657,7 +1657,7 @@ Future<T> Future<T>::within(Duration dur, E e, Timekeeper* tk) {
}
if (UNLIKELY(!tk)) {
return makeFuture<T>(NoTimekeeper());
return makeFuture<T>(FutureNoTimekeeper());
}
auto ctx = std::make_shared<Context>(std::move(e));
......@@ -1685,7 +1685,7 @@ Future<T> Future<T>::within(Duration dur, E e, Timekeeper* tk) {
return;
}
// "after" completed first, cancel "this"
lockedCtx->thisFuture.raise(TimedOut());
lockedCtx->thisFuture.raise(FutureTimeout());
if (lockedCtx->token.exchange(true) == false) {
if (t.hasException()) {
lockedCtx->promise.setException(std::move(t.exception()));
......@@ -1865,7 +1865,7 @@ Try<T> SemiFuture<T>::getTry(Duration dur) && {
this->core_ = nullptr;
if (!future.isReady()) {
throw_exception<TimedOut>();
throw_exception<FutureTimeout>();
}
return std::move(std::move(future).getTry());
}
......@@ -1927,7 +1927,7 @@ template <class T>
T Future<T>::get(Duration dur) {
wait(dur);
if (!this->isReady()) {
throw_exception<TimedOut>();
throw_exception<FutureTimeout>();
}
return std::move(this->value());
}
......@@ -1946,7 +1946,7 @@ template <class T>
T Future<T>::getVia(TimedDrivableExecutor* e, Duration dur) {
waitVia(e, dur);
if (!this->isReady()) {
throw_exception<TimedOut>();
throw_exception<FutureTimeout>();
}
return std::move(value());
}
......@@ -1960,7 +1960,7 @@ template <class T>
Try<T>& Future<T>::getTryVia(TimedDrivableExecutor* e, Duration dur) {
waitVia(e, dur);
if (!this->isReady()) {
throw_exception<TimedOut>();
throw_exception<FutureTimeout>();
}
return result();
}
......@@ -1994,7 +1994,7 @@ Future<T> Future<T>::filter(F&& predicate) {
return this->then([p = std::forward<F>(predicate)](T val) {
T const& valConstRef = val;
if (!p(valConstRef)) {
throw_exception<PredicateDoesNotObtain>();
throw_exception<FuturePredicateDoesNotObtain>();
}
return val;
});
......
......@@ -47,7 +47,7 @@ Future<Unit> sleep(Duration dur, Timekeeper* tk) {
}
if (UNLIKELY(!tk)) {
return makeFuture<Unit>(NoTimekeeper());
return makeFuture<Unit>(FutureNoTimekeeper());
}
return tk->after(dur);
......
......@@ -46,6 +46,47 @@
namespace folly {
class FOLLY_EXPORT FutureException : public std::logic_error {
public:
using std::logic_error::logic_error;
};
class FOLLY_EXPORT FutureInvalid : public FutureException {
public:
FutureInvalid() : FutureException("Future invalid") {}
};
class FOLLY_EXPORT FutureNotReady : public FutureException {
public:
FutureNotReady() : FutureException("Future not ready") {}
};
class FOLLY_EXPORT FutureCancellation : public FutureException {
public:
FutureCancellation() : FutureException("Future was cancelled") {}
};
class FOLLY_EXPORT FutureTimeout : public FutureException {
public:
FutureTimeout() : FutureException("Timed out") {}
};
class FOLLY_EXPORT FuturePredicateDoesNotObtain : public FutureException {
public:
FuturePredicateDoesNotObtain()
: FutureException("Predicate does not obtain") {}
};
class FOLLY_EXPORT FutureNoTimekeeper : public FutureException {
public:
FutureNoTimekeeper() : FutureException("No timekeeper available") {}
};
class FOLLY_EXPORT FutureNoExecutor : public FutureException {
public:
FutureNoExecutor() : FutureException("No executor provided to via") {}
};
template <class T>
class Future;
......@@ -101,7 +142,7 @@ class FutureBase {
/// qualification equivalent to the reference category and const-qualification
/// of the receiver.
///
/// If moved-from, throws NoState.
/// If moved-from, throws FutureInvalid.
///
/// If !isReady(), throws FutureNotReady.
///
......@@ -170,7 +211,8 @@ class FutureBase {
using CoreType = futures::detail::Core<T>;
using corePtr = CoreType*;
// Throws NoState if there is no shared state object; else returns it by ref.
// Throws FutureInvalid if there is no shared state object; else returns it
// by ref.
//
// Implementation methods should usually use this instead of `this->core_`.
// The latter should be used only when you need the possibly-null pointer.
......@@ -184,7 +226,7 @@ class FutureBase {
template <typename Self>
static decltype(auto) getCoreImpl(Self& self) {
if (!self.core_) {
throw_exception<NoState>();
throw_exception<FutureInvalid>();
}
return *self.core_;
}
......@@ -307,7 +349,7 @@ class SemiFuture : private futures::detail::FutureBase<T> {
T get() &&;
/// Block until the future is fulfilled, or until timed out. Returns the
/// value (moved out), or throws the exception (which might be a TimedOut
/// value (moved out), or throws the exception (which might be a FutureTimeout
/// exception).
T get(Duration dur) &&;
......@@ -316,7 +358,7 @@ class SemiFuture : private futures::detail::FutureBase<T> {
Try<T> getTry() &&;
/// Block until the future is fulfilled, or until timed out. Returns the
/// Try of the value (moved out) or may throw a TimedOut exception.
/// Try of the value (moved out) or may throw a FutureTimeout exception.
Try<T> getTry(Duration dur) &&;
/// Block until this Future is complete. Returns a reference to this Future.
......@@ -563,7 +605,7 @@ class Future : private futures::detail::FutureBase<T> {
T getVia(DrivableExecutor* e);
/// getVia but will wait only until timed out. Returns the
/// Try of the value (moved out) or may throw a TimedOut exception.
/// Try of the value (moved out) or may throw a FutureTimeout exception.
T getVia(TimedDrivableExecutor* e, Duration dur);
/// Call e->drive() repeatedly until the future is fulfilled. Examples
......@@ -572,7 +614,7 @@ class Future : private futures::detail::FutureBase<T> {
Try<T>& getTryVia(DrivableExecutor* e);
/// getTryVia but will wait only until timed out. Returns the
/// Try of the value (moved out) or may throw a TimedOut exception.
/// Try of the value (moved out) or may throw a FutureTimeout exception.
Try<T>& getTryVia(TimedDrivableExecutor* e, Duration dur);
/// Unwraps the case of a Future<Future<T>> instance, and returns a simple
......@@ -737,7 +779,7 @@ class Future : private futures::detail::FutureBase<T> {
template <class F>
Future<T> onTimeout(Duration, F&& func, Timekeeper* = nullptr);
/// Throw TimedOut if this Future does not complete within the given
/// Throw FutureTimeout if this Future does not complete within the given
/// duration from now. The optional Timeekeeper is as with futures::sleep().
Future<T> within(Duration, Timekeeper* = nullptr);
......@@ -756,7 +798,7 @@ class Future : private futures::detail::FutureBase<T> {
T get();
/// Block until the future is fulfilled, or until timed out. Returns the
/// value (moved out), or throws the exception (which might be a TimedOut
/// value (moved out), or throws the exception (which might be a FutureTimeout
/// exception).
T get(Duration dur);
......@@ -800,7 +842,7 @@ class Future : private futures::detail::FutureBase<T> {
/// predicate behaves like std::function<bool(T const&)>
/// If the predicate does not obtain with the value, the result
/// is a folly::PredicateDoesNotObtain exception
/// is a folly::FuturePredicateDoesNotObtain exception
template <class F>
Future<T> filter(F&& predicate);
......
/*
* Copyright 2014-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdexcept>
#include <string>
#include <folly/CPortability.h>
namespace folly {
class FOLLY_EXPORT FutureException : public std::logic_error {
public:
using std::logic_error::logic_error;
};
class FOLLY_EXPORT BrokenPromise : public FutureException {
public:
explicit BrokenPromise(const std::string& type)
: FutureException("Broken promise for type name `" + type + '`') {}
explicit BrokenPromise(const char* type) : BrokenPromise(std::string(type)) {}
};
class FOLLY_EXPORT NoState : public FutureException {
public:
NoState() : FutureException("No state") {}
};
class FOLLY_EXPORT PromiseAlreadySatisfied : public FutureException {
public:
PromiseAlreadySatisfied() : FutureException("Promise already satisfied") {}
};
class FOLLY_EXPORT FutureNotReady : public FutureException {
public:
FutureNotReady() : FutureException("Future not ready") {}
};
class FOLLY_EXPORT FutureAlreadyRetrieved : public FutureException {
public:
FutureAlreadyRetrieved() : FutureException("Future already retrieved") {}
};
class FOLLY_EXPORT FutureCancellation : public FutureException {
public:
FutureCancellation() : FutureException("Future was cancelled") {}
};
class FOLLY_EXPORT TimedOut : public FutureException {
public:
TimedOut() : FutureException("Timed out") {}
};
class FOLLY_EXPORT PredicateDoesNotObtain : public FutureException {
public:
PredicateDoesNotObtain() : FutureException("Predicate does not obtain") {}
};
class FOLLY_EXPORT NoFutureInSplitter : public FutureException {
public:
NoFutureInSplitter() : FutureException("No Future in this FutureSplitter") {}
};
class FOLLY_EXPORT NoTimekeeper : public FutureException {
public:
NoTimekeeper() : FutureException("No timekeeper available") {}
};
class FOLLY_EXPORT NoExecutor : public FutureException {
public:
NoExecutor() : FutureException("No executor provided to via") {}
};
} // namespace folly
......@@ -22,6 +22,12 @@
namespace folly {
class FOLLY_EXPORT FutureSplitterInvalid : public FutureException {
public:
FutureSplitterInvalid()
: FutureException("No Future in this FutureSplitter") {}
};
/*
* FutureSplitter provides a `getFuture()' method which can be called multiple
* times, returning a new Future each time. These futures are completed when the
......@@ -55,7 +61,7 @@ class FutureSplitter {
*/
Future<T> getFuture() {
if (promise_ == nullptr) {
throw_exception<NoFutureInSplitter>();
throw_exception<FutureSplitterInvalid>();
}
return promise_->getSemiFuture().via(e_);
}
......@@ -65,7 +71,7 @@ class FutureSplitter {
*/
SemiFuture<T> getSemiFuture() {
if (promise_ == nullptr) {
throw_exception<NoFutureInSplitter>();
throw_exception<FutureSplitterInvalid>();
}
return promise_->getSemiFuture();
}
......
......@@ -20,7 +20,6 @@
#include <thread>
#include <folly/executors/InlineExecutor.h>
#include <folly/futures/FutureException.h>
#include <folly/futures/detail/Core.h>
namespace folly {
......
......@@ -20,11 +20,38 @@
#include <folly/Portability.h>
#include <folly/Try.h>
#include <folly/futures/FutureException.h>
#include <folly/lang/Exception.h>
namespace folly {
class FOLLY_EXPORT PromiseException : public std::logic_error {
public:
using std::logic_error::logic_error;
};
class FOLLY_EXPORT PromiseInvalid : public PromiseException {
public:
PromiseInvalid() : PromiseException("Promise invalid") {}
};
class FOLLY_EXPORT PromiseAlreadySatisfied : public PromiseException {
public:
PromiseAlreadySatisfied() : PromiseException("Promise already satisfied") {}
};
class FOLLY_EXPORT FutureAlreadyRetrieved : public PromiseException {
public:
FutureAlreadyRetrieved() : PromiseException("Future already retrieved") {}
};
class FOLLY_EXPORT BrokenPromise : public PromiseException {
public:
explicit BrokenPromise(const std::string& type)
: PromiseException("Broken promise for type name `" + type + '`') {}
explicit BrokenPromise(const char* type) : BrokenPromise(std::string(type)) {}
};
// forward declaration
template <class T>
class SemiFuture;
......@@ -145,7 +172,8 @@ class Promise {
using CoreType = typename Future<T>::CoreType;
using corePtr = typename Future<T>::corePtr;
// Throws NoState if there is no shared state object; else returns it by ref.
// Throws PromiseInvalid if there is no shared state object; else returns it
// by ref.
//
// Implementation methods should usually use this instead of `this->core_`.
// The latter should be used only when you need the possibly-null pointer.
......@@ -159,7 +187,7 @@ class Promise {
template <typename CoreT>
static CoreT& getCoreImpl(CoreT* core) {
if (!core) {
throw_exception<NoState>();
throw_exception<PromiseInvalid>();
}
return *core;
}
......
......@@ -747,12 +747,12 @@ Although inspired by the C++11 std::future interface, it is not a drop-in replac
<h2 id="within">within() <a href="#within" class="headerLink">#</a></h2>
<p><tt>Future&lt;T&gt;::within()</tt> returns a new Future that will complete with the provided exception (by default, a TimedOut exception) if it does not complete within the specified duration. For example:</p>
<p><tt>Future&lt;T&gt;::within()</tt> returns a new Future that will complete with the provided exception (by default, a FutureTimeout exception) if it does not complete within the specified duration. For example:</p>
<div class="remarkup-code-block" data-code-lang="cpp"><pre class="remarkup-code"><span class="k">using</span><span class=""> </span><span class="n">std</span><span class="o">:</span><span class="o">:</span><span class="n">chrono</span><span class="o">:</span><span class="o">:</span><span class="n">milliseconds</span><span class="p">;</span><span class="">
</span><span class="n">Future</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class=""> </span><span class="n">foo</span><span class="p">(</span><span class="p">)</span><span class="p">;</span><span class="">
</span><span class="">
</span><span class="c1">// f will complete with a TimedOut exception if the Future returned by foo()
</span><span class="c1">// f will complete with a FutureTimeout exception if the Future returned by foo()
</span><span class="c1">// does not complete within 500 ms
</span><span class="n">f</span><span class=""> </span><span class="o">=</span><span class=""> </span><span class="n">foo</span><span class="p">(</span><span class="p">)</span><span class="p">.</span><span class="n">within</span><span class="p">(</span><span class="n">milliseconds</span><span class="p">(</span><span class="mi">500</span><span class="p">)</span><span class="p">)</span><span class="p">;</span><span class="">
</span><span class="">
......@@ -778,7 +778,7 @@ Although inspired by the C++11 std::future interface, it is not a drop-in replac
<div class="remarkup-code-block" data-code-lang="cpp"><pre class="remarkup-code"><span class="n">foo</span><span class="p">(</span><span class="p">)</span><span class="">
</span><span class=""> </span><span class="p">.</span><span class="n">within</span><span class="p">(</span><span class="n">milliseconds</span><span class="p">(</span><span class="mi">500</span><span class="p">)</span><span class="p">)</span><span class="">
</span><span class=""> </span><span class="p">.</span><span class="n">onError</span><span class="p">(</span><span class="p">[</span><span class="p">]</span><span class="p">(</span><span class="k">const</span><span class=""> </span><span class="n">TimedOut</span><span class="o">&amp;</span><span class=""> </span><span class="n">e</span><span class="p">)</span><span class=""> </span><span class="p">&#123;</span><span class="">
</span><span class=""> </span><span class="p">.</span><span class="n">onError</span><span class="p">(</span><span class="p">[</span><span class="p">]</span><span class="p">(</span><span class="k">const</span><span class=""> </span><span class="n">FutureTimeout</span><span class="o">&amp;</span><span class=""> </span><span class="n">e</span><span class="p">)</span><span class=""> </span><span class="p">&#123;</span><span class="">
</span><span class=""> </span><span class="c1">// handle timeout
</span><span class=""> </span><span class="k">return</span><span class=""> </span><span class="o">-</span><span class="mi">1</span><span class="p">;</span><span class="">
</span><span class=""> </span><span class="p">&#125;</span><span class="p">)</span><span class="">
......@@ -790,7 +790,7 @@ Although inspired by the C++11 std::future interface, it is not a drop-in replac
<p><tt>get()</tt> and <tt>wait()</tt>, which are detailed in the <a href="#testing">Testing</a> article, optionally take timeouts:</p>
<div class="remarkup-code-block" data-code-lang="cpp"><pre class="remarkup-code"><span class="n">Future</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class=""> </span><span class="n">foo</span><span class="p">(</span><span class="p">)</span><span class="p">;</span><span class="">
</span><span class="c1">// Will throw TimedOut if the Future doesn&#039;t complete within one second of
</span><span class="c1">// Will throw FutureTimeout if the Future doesn&#039;t complete within one second of
</span><span class="c1">// the get() call
</span><span class="kt">int</span><span class=""> </span><span class="n">result</span><span class=""> </span><span class="o">=</span><span class=""> </span><span class="n">foo</span><span class="p">(</span><span class="p">)</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">milliseconds</span><span class="p">(</span><span class="mi">1000</span><span class="p">)</span><span class="p">)</span><span class="p">;</span><span class="">
</span><span class="">
......@@ -887,7 +887,7 @@ Although inspired by the C++11 std::future interface, it is not a drop-in replac
<div class="remarkup-code-block" data-code-lang="cpp"><pre class="remarkup-code"><span class="n">EXPECT_TRUE</span><span class="p">(</span><span class="n">isPrime</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="p">)</span><span class="p">)</span><span class="p">;</span><span class="">
</span></pre></div>
<p>Keep in mind that some other thread had better complete the Future, because the thread that calls <tt>get()</tt> will block. Also, <tt>get()</tt> optionally takes a timeout after which its throws a TimedOut exception. See the <a href="#timeouts-and-related-features">Timeouts</a> article for more information.</p>
<p>Keep in mind that some other thread had better complete the Future, because the thread that calls <tt>get()</tt> will block. Also, <tt>get()</tt> optionally takes a timeout after which its throws a FutureTimeout exception. See the <a href="#timeouts-and-related-features">Timeouts</a> article for more information.</p>
<h3 id="wait">wait() <a href="#wait" class="headerLink">#</a></h3>
......
......@@ -71,7 +71,7 @@ struct WTCallback : public std::enable_shared_from_this<WTCallback>,
// Don't need Promise anymore, break the circular reference
auto promise = stealPromise();
if (!promise.isFulfilled()) {
promise.setException(NoTimekeeper{});
promise.setException(FutureNoTimekeeper{});
}
}
......@@ -142,7 +142,7 @@ Future<Unit> ThreadWheelTimekeeper::after(Duration dur) {
// I don't see it is introducing any problem yet.
auto promise = cob->stealPromise();
if (!promise.isFulfilled()) {
promise.setException(NoTimekeeper{});
promise.setException(FutureNoTimekeeper{});
}
}
return f;
......
......@@ -24,8 +24,9 @@ TEST(Filter, alwaysTrye) {
}
TEST(Filter, alwaysFalse) {
EXPECT_THROW(makeFuture(42).filter([](int){ return false; }).get(),
folly::PredicateDoesNotObtain);
EXPECT_THROW(
makeFuture(42).filter([](int) { return false; }).get(),
folly::FuturePredicateDoesNotObtain);
}
TEST(Filter, moveOnlyValue) {
......
......@@ -42,7 +42,7 @@ static eggs_t eggs("eggs");
TEST(Future, makeEmpty) {
auto f = Future<int>::makeEmpty();
EXPECT_THROW(f.isReady(), NoState);
EXPECT_THROW(f.isReady(), FutureInvalid);
}
TEST(Future, futureDefaultCtor) {
......@@ -147,7 +147,8 @@ TEST(Future, ctorPostconditionInvalid) {
}
TEST(Future, lacksPreconditionValid) {
// Ops that don't throw NoState if !valid() -- without precondition: valid()
// Ops that don't throw FutureInvalid if !valid() --
// without precondition: valid()
#define DOIT(STMT) \
do { \
......@@ -179,14 +180,15 @@ TEST(Future, lacksPreconditionValid) {
}
TEST(Future, hasPreconditionValid) {
// Ops that require validity; precondition: valid(); throw NoState if !valid()
#define DOIT(STMT) \
do { \
auto f = makeValid(); \
EXPECT_NO_THROW(STMT); \
copy(std::move(f)); \
EXPECT_THROW(STMT, NoState); \
// Ops that require validity; precondition: valid();
// throw FutureInvalid if !valid()
#define DOIT(STMT) \
do { \
auto f = makeValid(); \
EXPECT_NO_THROW(STMT); \
copy(std::move(f)); \
EXPECT_THROW(STMT, FutureInvalid); \
} while (false)
DOIT(f.isReady());
......
......@@ -108,7 +108,8 @@ TEST(Promise, ctorPostconditionInvalid) {
}
TEST(Promise, lacksPreconditionValid) {
// Ops that don't throw NoState if !valid() -- without precondition: valid()
// Ops that don't throw PromiseInvalid if !valid() --
// without precondition: valid()
#define DOIT(STMT) \
do { \
......@@ -141,14 +142,15 @@ TEST(Promise, lacksPreconditionValid) {
}
TEST(Promise, hasPreconditionValid) {
// Ops that require validity; precondition: valid(); throw NoState if !valid()
#define DOIT(STMT) \
do { \
auto p = makeValid(); \
EXPECT_NO_THROW(STMT); \
copy(std::move(p)); \
EXPECT_THROW(STMT, NoState); \
// Ops that require validity; precondition: valid();
// throw PromiseInvalid if !valid()
#define DOIT(STMT) \
do { \
auto p = makeValid(); \
EXPECT_NO_THROW(STMT); \
copy(std::move(p)); \
EXPECT_THROW(STMT, PromiseInvalid); \
} while (false)
auto const except = std::logic_error("foo");
......
......@@ -42,7 +42,7 @@ static eggs_t eggs("eggs");
TEST(SemiFuture, makeEmpty) {
auto f = SemiFuture<int>::makeEmpty();
EXPECT_THROW(f.isReady(), NoState);
EXPECT_THROW(f.isReady(), FutureInvalid);
}
TEST(SemiFuture, futureDefaultCtor) {
......@@ -121,7 +121,8 @@ TEST(SemiFuture, ctorPostconditionInvalid) {
}
TEST(SemiFuture, lacksPreconditionValid) {
// Ops that don't throw NoState if !valid() -- without precondition: valid()
// Ops that don't throw FutureInvalid if !valid() --
// without precondition: valid()
#define DOIT(STMT) \
do { \
......@@ -153,14 +154,15 @@ TEST(SemiFuture, lacksPreconditionValid) {
}
TEST(SemiFuture, hasPreconditionValid) {
// Ops that require validity; precondition: valid(); throw NoState if !valid()
#define DOIT(STMT) \
do { \
auto f = makeValid(); \
EXPECT_NO_THROW(STMT); \
copy(std::move(f)); \
EXPECT_THROW(STMT, NoState); \
// Ops that require validity; precondition: valid();
// throw FutureInvalid if !valid()
#define DOIT(STMT) \
do { \
auto f = makeValid(); \
EXPECT_NO_THROW(STMT); \
copy(std::move(f)); \
EXPECT_THROW(STMT, FutureInvalid); \
} while (false)
DOIT(f.isReady());
......@@ -340,12 +342,12 @@ TEST(SemiFuture, makeSemiFutureNoThrow) {
}
TEST(SemiFuture, ViaThrowOnNull) {
EXPECT_THROW(makeSemiFuture().via(nullptr), NoExecutor);
EXPECT_THROW(makeSemiFuture().via(nullptr), FutureNoExecutor);
}
TEST(SemiFuture, ConstructSemiFutureFromEmptyFuture) {
auto f = SemiFuture<int>{Future<int>::makeEmpty()};
EXPECT_THROW(f.isReady(), NoState);
EXPECT_THROW(f.isReady(), FutureInvalid);
}
TEST(SemiFuture, ConstructSemiFutureFromFutureDefaultCtor) {
......@@ -481,7 +483,8 @@ TEST(SemiFuture, SimpleGetTry) {
TEST(SemiFuture, SimpleTimedGet) {
Promise<folly::Unit> p;
auto sf = p.getSemiFuture();
EXPECT_THROW(std::move(sf).get(std::chrono::milliseconds(100)), TimedOut);
EXPECT_THROW(
std::move(sf).get(std::chrono::milliseconds(100)), FutureTimeout);
}
TEST(SemiFuture, SimpleTimedWait) {
......@@ -510,13 +513,14 @@ TEST(SemiFuture, SimpleTimedGetViaFromSemiFuture) {
auto sf = p.getSemiFuture();
EXPECT_THROW(
std::move(sf).via(&e2).getVia(&e2, std::chrono::milliseconds(100)),
TimedOut);
FutureTimeout);
}
TEST(SemiFuture, SimpleTimedGetTry) {
Promise<folly::Unit> p;
auto sf = p.getSemiFuture();
EXPECT_THROW(std::move(sf).getTry(std::chrono::milliseconds(100)), TimedOut);
EXPECT_THROW(
std::move(sf).getTry(std::chrono::milliseconds(100)), FutureTimeout);
}
TEST(SemiFuture, SimpleTimedGetTryViaFromSemiFuture) {
......@@ -525,7 +529,7 @@ TEST(SemiFuture, SimpleTimedGetTryViaFromSemiFuture) {
auto sf = p.getSemiFuture();
EXPECT_THROW(
std::move(sf).via(&e2).getTryVia(&e2, std::chrono::milliseconds(100)),
TimedOut);
FutureTimeout);
}
TEST(SemiFuture, SimpleValue) {
......@@ -615,7 +619,8 @@ TEST(SemiFuture, DeferWithGetTimedGet) {
Promise<folly::Unit> p;
auto f = p.getSemiFuture().toUnsafeFuture();
auto sf = std::move(f).semi().defer([&]() { innerResult = 17; });
EXPECT_THROW(std::move(sf).get(std::chrono::milliseconds(100)), TimedOut);
EXPECT_THROW(
std::move(sf).get(std::chrono::milliseconds(100)), FutureTimeout);
ASSERT_EQ(innerResult, 0);
}
......
......@@ -71,7 +71,7 @@ TEST(Timekeeper, futureGetBeforeTimeout) {
TEST(Timekeeper, futureGetTimeout) {
Promise<int> p;
EXPECT_THROW(p.getFuture().get(one_ms), folly::TimedOut);
EXPECT_THROW(p.getFuture().get(one_ms), folly::FutureTimeout);
}
TEST(Timekeeper, futureSleep) {
......@@ -85,7 +85,7 @@ TEST(Timekeeper, futureSleepHandlesNullTimekeeperSingleton) {
SCOPE_EXIT {
Singleton<ThreadWheelTimekeeper>::make_mock();
};
EXPECT_THROW(futures::sleep(one_ms).get(), NoTimekeeper);
EXPECT_THROW(futures::sleep(one_ms).get(), FutureNoTimekeeper);
}
TEST(Timekeeper, futureWithinHandlesNullTimekeeperSingleton) {
......@@ -95,7 +95,7 @@ TEST(Timekeeper, futureWithinHandlesNullTimekeeperSingleton) {
};
Promise<int> p;
auto f = p.getFuture().within(one_ms);
EXPECT_THROW(f.get(), NoTimekeeper);
EXPECT_THROW(f.get(), FutureNoTimekeeper);
}
TEST(Timekeeper, futureDelayed) {
......@@ -110,17 +110,15 @@ TEST(Timekeeper, futureDelayed) {
TEST(Timekeeper, futureWithinThrows) {
Promise<int> p;
auto f = p.getFuture()
.within(one_ms)
.onError([](TimedOut&) { return -1; });
auto f =
p.getFuture().within(one_ms).onError([](FutureTimeout&) { return -1; });
EXPECT_EQ(-1, f.get());
}
TEST(Timekeeper, futureWithinAlreadyComplete) {
auto f = makeFuture(42)
.within(one_ms)
.onError([&](TimedOut&){ return -1; });
auto f =
makeFuture(42).within(one_ms).onError([&](FutureTimeout&) { return -1; });
EXPECT_EQ(42, f.get());
}
......@@ -128,8 +126,8 @@ TEST(Timekeeper, futureWithinAlreadyComplete) {
TEST(Timekeeper, futureWithinFinishesInTime) {
Promise<int> p;
auto f = p.getFuture()
.within(std::chrono::minutes(1))
.onError([&](TimedOut&){ return -1; });
.within(std::chrono::minutes(1))
.onError([&](FutureTimeout&) { return -1; });
p.setValue(42);
EXPECT_EQ(42, f.get());
......@@ -236,7 +234,7 @@ TEST(Timekeeper, onTimeoutPropagates) {
makeFuture(42).delayed(one_ms)
.onTimeout(zero_ms, [&]{ flag = true; })
.get(),
TimedOut);
FutureTimeout);
EXPECT_TRUE(flag);
}
*/
......
......@@ -404,7 +404,7 @@ TEST(Via, SimpleTimedGetVia) {
TimedDrivableExecutor e2;
Promise<folly::Unit> p;
auto f = p.getFuture();
EXPECT_THROW(f.getVia(&e2, std::chrono::seconds(1)), TimedOut);
EXPECT_THROW(f.getVia(&e2, std::chrono::seconds(1)), FutureTimeout);
}
TEST(Via, getTryVia) {
......@@ -437,7 +437,7 @@ TEST(Via, SimpleTimedGetTryVia) {
TimedDrivableExecutor e2;
Promise<folly::Unit> p;
auto f = p.getFuture();
EXPECT_THROW(f.getTryVia(&e2, std::chrono::seconds(1)), TimedOut);
EXPECT_THROW(f.getTryVia(&e2, std::chrono::seconds(1)), FutureTimeout);
}
TEST(Via, waitVia) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment