Skip to content

Commit

Permalink
Clarify the error message when an AsyncFunction returns null (*not* a…
Browse files Browse the repository at this point in the history
… Future that contains null).

Add a similar message for FutureFallback.
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=84565778
  • Loading branch information
cpovirk committed Jan 29, 2015
1 parent 8f1df29 commit e376c4d
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 10 deletions.
Expand Up @@ -451,9 +451,9 @@ public void run() {
return;
}

ListenableFuture<? extends O> outputFuture =
Preconditions.checkNotNull(function.apply(sourceResult),
"AsyncFunction may not return null.");
ListenableFuture<? extends O> outputFuture = function.apply(sourceResult);
checkNotNull(outputFuture, "AsyncFunction.apply returned null instead of a Future. "
+ "Did you mean to return immediateFuture(null)?");
setFuture(outputFuture);
} catch (UndeclaredThrowableException e) {
// Set the cause of the exception as this future's exception
Expand Down
Expand Up @@ -685,8 +685,26 @@ public void testWithFallback_resultCancelledAfterFallback() throws Exception {
mocksControl.verify();
}

public void testWithFallback_nullInsteadOfFuture() throws Exception {
ListenableFuture<?> inputFuture = immediateFailedFuture(new Exception());
ListenableFuture<?> chainedFuture =
Futures.withFallback(inputFuture, new FutureFallback<Integer>() {
@Override public ListenableFuture<Integer> create(Throwable t) {
return null;
}
});
try {
chainedFuture.get();
fail();
} catch (ExecutionException expected) {
NullPointerException cause = (NullPointerException) expected.getCause();
assertThat(cause).hasMessage("FutureFallback.create returned null instead of a Future. "
+ "Did you mean to return immediateFuture(null)?");
}
}

public void testTransform_genericsWildcard_AsyncFunction() throws Exception {
ListenableFuture<?> nullFuture = Futures.immediateFuture(null);
ListenableFuture<?> nullFuture = immediateFuture(null);
ListenableFuture<?> chainedFuture =
Futures.transform(nullFuture, constantAsyncFunction(nullFuture));
assertNull(chainedFuture.get());
Expand Down Expand Up @@ -746,6 +764,20 @@ public void testTransform_asyncFunction_error() throws InterruptedException {
}
}

public void testTransform_asyncFunction_nullInsteadOfFuture() throws Exception {
ListenableFuture<?> inputFuture = immediateFuture("a");
ListenableFuture<?> chainedFuture =
Futures.transform(inputFuture, constantAsyncFunction(null));
try {
chainedFuture.get();
fail();
} catch (ExecutionException expected) {
NullPointerException cause = (NullPointerException) expected.getCause();
assertThat(cause).hasMessage("AsyncFunction.apply returned null instead of a Future. "
+ "Did you mean to return immediateFuture(null)?");
}
}

public void testTransform_asyncFunction_cancelledWhileApplyingFunction()
throws InterruptedException, ExecutionException {
final CountDownLatch inFunction = new CountDownLatch(1);
Expand Down Expand Up @@ -1031,8 +1063,8 @@ public void testAllAsList_resultCancelled_withSecondaryListFuture()
SettableFuture<String> future2 = SettableFuture.create();
ListenableFuture<List<String>> compound =
Futures.allAsList(future1, future2);
ListenableFuture<List<String>> otherCompound =
Futures.allAsList(future1, future2);
// This next call is "unused," but it is an important part of the test. Don't remove it!
Futures.allAsList(future1, future2);

assertTrue(compound.cancel(false));
assertTrue(future1.isCancelled());
Expand Down
11 changes: 7 additions & 4 deletions guava/src/com/google/common/util/concurrent/Futures.java
Expand Up @@ -495,7 +495,10 @@ private static class FallbackFuture<V> extends AbstractFuture.TrustedFuture<V> {
throwable = e;
}
try {
setFuture(fallback.create(throwable));
ListenableFuture<? extends V> replacement = fallback.create(throwable);
checkNotNull(replacement, "FutureFallback.create returned null instead of a Future. "
+ "Did you mean to return immediateFuture(null)?");
setFuture(replacement);
} catch (Throwable e) {
setException(e);
}
Expand Down Expand Up @@ -911,9 +914,9 @@ public void run() {
return;
}

ListenableFuture<? extends O> outputFuture =
Preconditions.checkNotNull(function.apply(sourceResult),
"AsyncFunction may not return null.");
ListenableFuture<? extends O> outputFuture = function.apply(sourceResult);
checkNotNull(outputFuture, "AsyncFunction.apply returned null instead of a Future. "
+ "Did you mean to return immediateFuture(null)?");
setFuture(outputFuture);
} catch (UndeclaredThrowableException e) {
// Set the cause of the exception as this future's exception
Expand Down

0 comments on commit e376c4d

Please sign in to comment.