Merge "Fix double-wrapping of exceptions in remote AndroidFutures."

This commit is contained in:
Alexander Dorokhine
2019-12-17 18:36:24 +00:00
committed by Android (Google) Code Review
2 changed files with 33 additions and 1 deletions

View File

@@ -531,6 +531,12 @@ public class AndroidFuture<T> extends CompletableFuture<T> implements Parcelable
try {
AndroidFuture.this.complete((T) resultContainer.get());
} catch (Throwable t) {
// If resultContainer was completed exceptionally, get() wraps the
// underlying exception in an ExecutionException. Unwrap it now to avoid
// double-layering ExecutionExceptions.
if (t instanceof ExecutionException && t.getCause() != null) {
t = t.getCause();
}
completeExceptionally(t);
}
}

View File

@@ -111,7 +111,7 @@ public class AndroidFutureTest {
}
@Test
public void testWriteToParcel_Exceptionally() throws Exception {
public void testWriteToParcel_Exception() throws Exception {
Parcel parcel = Parcel.obtain();
AndroidFuture<Integer> future1 = new AndroidFuture<>();
future1.completeExceptionally(new UnsupportedOperationException());
@@ -123,4 +123,30 @@ public class AndroidFutureTest {
expectThrows(ExecutionException.class, future2::get);
assertThat(executionException.getCause()).isInstanceOf(UnsupportedOperationException.class);
}
@Test
public void testWriteToParcel_Incomplete() throws Exception {
Parcel parcel = Parcel.obtain();
AndroidFuture<Integer> future1 = new AndroidFuture<>();
future1.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
AndroidFuture future2 = AndroidFuture.CREATOR.createFromParcel(parcel);
future2.complete(5);
assertThat(future1.get()).isEqualTo(5);
}
@Test
public void testWriteToParcel_Incomplete_Exception() throws Exception {
Parcel parcel = Parcel.obtain();
AndroidFuture<Integer> future1 = new AndroidFuture<>();
future1.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
AndroidFuture future2 = AndroidFuture.CREATOR.createFromParcel(parcel);
future2.completeExceptionally(new UnsupportedOperationException());
ExecutionException executionException =
expectThrows(ExecutionException.class, future1::get);
assertThat(executionException.getCause()).isInstanceOf(UnsupportedOperationException.class);
}
}