public static <T> ListenableFuture<T> catchingThriftException(ListenableFuture<T> future) { return catchingAsync(future, Exception.class, e -> immediateFailedFuture(toPrestoException(e))); } }
public void testCatchingAsync_inputDoesNotRaiseException() throws Exception { AsyncFunction<Throwable, Integer> fallback = unexpectedAsyncFunction(); ListenableFuture<Integer> originalFuture = immediateFuture(7); ListenableFuture<Integer> faultTolerantFuture = catchingAsync(originalFuture, Throwable.class, fallback, directExecutor()); assertEquals(7, getDone(faultTolerantFuture).intValue()); }
public void testCatchingAsync_fallbackNotReady() throws Exception { ListenableFuture<Integer> primary = immediateFailedFuture(new Exception()); final SettableFuture<Integer> secondary = SettableFuture.create(); AsyncFunction<Throwable, Integer> fallback = new AsyncFunction<Throwable, Integer>() { @Override public ListenableFuture<Integer> apply(Throwable t) { return secondary; } }; ListenableFuture<Integer> derived = catchingAsync(primary, Throwable.class, fallback, directExecutor()); secondary.set(1); assertEquals(1, (int) getDone(derived)); }
public void testCatchingAsync_rejectionPropagatesToOutput() throws Exception { SettableFuture<String> input = SettableFuture.create(); ListenableFuture<String> transformed = catchingAsync( input, Throwable.class, constantAsyncFunction(immediateFuture("foo")), REJECTING_EXECUTOR); input.setException(new Exception()); try { getDone(transformed); fail(); } catch (ExecutionException expected) { assertThat(expected.getCause()).isInstanceOf(RejectedExecutionException.class); } }
public void testCatchingAsync_futureToString() throws Exception { final SettableFuture<Object> toReturn = SettableFuture.create(); AsyncFunction<Object, Object> function = new AsyncFunction<Object, Object>() { @Override public ListenableFuture<Object> apply(Object input) throws Exception { return toReturn; } @Override public String toString() { return "Called my toString"; } }; ListenableFuture<?> output = Futures.catchingAsync( immediateFailedFuture(new RuntimeException()), Throwable.class, function, directExecutor()); assertThat(output.toString()).contains(toReturn.toString()); }
public void testCatchingAsync_ExceptionAfterCancellation() throws Exception { class Fallback implements AsyncFunction<Throwable, Object> { ListenableFuture<Object> output; @Override public ListenableFuture<Object> apply(Throwable input) { output.cancel(false); throw new MyRuntimeException(); } } Fallback fallback = new Fallback(); SettableFuture<Object> input = SettableFuture.create(); ListenableFuture<Object> output = catchingAsync(input, Throwable.class, fallback, directExecutor()); fallback.output = output; input.setException(new MyException()); assertTrue(output.isCancelled()); }
public void testCatchingAsync_ErrorAfterCancellation() throws Exception { class Fallback implements AsyncFunction<Throwable, Object> { ListenableFuture<Object> output; @Override public ListenableFuture<Object> apply(Throwable input) { output.cancel(false); throw new MyError(); } } Fallback fallback = new Fallback(); SettableFuture<Object> input = SettableFuture.create(); ListenableFuture<Object> output = catchingAsync(input, Throwable.class, fallback, directExecutor()); fallback.output = output; input.setException(new MyException()); assertTrue(output.isCancelled()); }
public void testCatchingAsync_fallbackGeneratesError() throws Exception { final Error error = new Error("deliberate"); AsyncFunction<Throwable, Integer> fallback = new AsyncFunction<Throwable, Integer>() { @Override public ListenableFuture<Integer> apply(Throwable t) throws Exception { throw error; } }; ListenableFuture<Integer> failingFuture = immediateFailedFuture(new RuntimeException()); try { getDone(catchingAsync(failingFuture, Throwable.class, fallback, directExecutor())); fail(); } catch (ExecutionException expected) { assertSame(error, expected.getCause()); } }
public void testCatchingAsync_Throwable() throws Exception { AsyncFunction<Throwable, Integer> fallback = asyncFunctionReturningOne(); ListenableFuture<Integer> originalFuture = immediateFailedFuture(new IOException()); ListenableFuture<Integer> faultTolerantFuture = catchingAsync(originalFuture, Throwable.class, fallback, directExecutor()); assertEquals(1, (int) getDone(faultTolerantFuture)); }
public void testCatchingAsync_listenerThrowsError() throws Exception { SettableFuture<Object> input = SettableFuture.create(); ListenableFuture<Object> output = catchingAsync(input, Throwable.class, asyncIdentity(), directExecutor()); output.addListener( new Runnable() { @Override public void run() { throw new MyError(); } }, directExecutor()); try { input.setException(new MyException()); fail(); } catch (MyError expected) { } }
@GwtIncompatible // StackOverflowError public void testCatchingAsync_StackOverflow() throws Exception { { /* * Initialize all relevant classes before running the test, which may otherwise poison any * classes it is trying to load during its stack overflow. */ SettableFuture<Object> root = SettableFuture.create(); ListenableFuture<Object> unused = catchingAsync(root, MyException.class, asyncIdentity(), directExecutor()); root.setException(new MyException()); } SettableFuture<Object> root = SettableFuture.create(); ListenableFuture<Object> output = root; for (int i = 0; i < 10000; i++) { output = catchingAsync(output, MyException.class, asyncIdentity(), directExecutor()); } try { root.setException(new MyException()); fail(); } catch (StackOverflowError expected) { } }
@GwtIncompatible // non-Throwable exceptionType public void testCatchingAsync_customTypeNoMatch() throws Exception { AsyncFunction<IOException, Integer> fallback = asyncFunctionReturningOne(); ListenableFuture<Integer> originalFuture = immediateFailedFuture(new RuntimeException()); ListenableFuture<Integer> faultTolerantFuture = catchingAsync(originalFuture, IOException.class, fallback, directExecutor()); try { getDone(faultTolerantFuture); fail(); } catch (ExecutionException expected) { assertThat(expected.getCause()).isInstanceOf(RuntimeException.class); } }
public void testCatchingAsync_getThrowsError() throws Exception { ListenableFuture<Object> input = UncheckedThrowingFuture.throwingError(new MyError()); // We'd catch only MyError.class here, but then the test won't compile under GWT. ListenableFuture<Object> output = catchingAsync(input, Throwable.class, asyncIdentity(), directExecutor()); assertThat(getDone(output)).isInstanceOf(MyError.class); }
@GwtIncompatible // non-Throwable exceptionType public void testCatchingAsync_customTypeMatch() throws Exception { AsyncFunction<IOException, Integer> fallback = asyncFunctionReturningOne(); ListenableFuture<Integer> originalFuture = immediateFailedFuture(new FileNotFoundException()); ListenableFuture<Integer> faultTolerantFuture = catchingAsync(originalFuture, IOException.class, fallback, directExecutor()); assertEquals(1, (int) getDone(faultTolerantFuture)); }
public void testCatchingAsync_getThrowsRuntimeException() throws Exception { ListenableFuture<Object> input = UncheckedThrowingFuture.throwingRuntimeException(new MyRuntimeException()); // We'd catch only MyRuntimeException.class here, but then the test won't compile under GWT. ListenableFuture<Object> output = catchingAsync(input, Throwable.class, asyncIdentity(), directExecutor()); assertThat(getDone(output)).isInstanceOf(MyRuntimeException.class); }
public void testCatchingAsync_inputRaisesException() throws Exception { final RuntimeException raisedException = new RuntimeException(); AsyncFunctionSpy<Throwable, Integer> fallback = spy( new AsyncFunction<Throwable, Integer>() { @Override public ListenableFuture<Integer> apply(Throwable t) throws Exception { assertThat(t).isSameAs(raisedException); return immediateFuture(20); } }); ListenableFuture<Integer> failingFuture = immediateFailedFuture(raisedException); ListenableFuture<Integer> faultTolerantFuture = catchingAsync(failingFuture, Throwable.class, fallback, directExecutor()); assertEquals(20, getDone(faultTolerantFuture).intValue()); fallback.verifyCallCount(1); }
public void testCatchingAsync_resultInterruptedBeforeFallback() throws Exception { SettableFuture<Integer> primary = SettableFuture.create(); AsyncFunction<Throwable, Integer> fallback = unexpectedAsyncFunction(); ListenableFuture<Integer> derived = catchingAsync(primary, Throwable.class, fallback, directExecutor()); derived.cancel(true); assertTrue(primary.isCancelled()); assertTrue(primary.wasInterrupted()); }
public void testCatchingAsync_resultCancelledBeforeFallback() throws Exception { SettableFuture<Integer> primary = SettableFuture.create(); AsyncFunction<Throwable, Integer> fallback = unexpectedAsyncFunction(); ListenableFuture<Integer> derived = catchingAsync(primary, Throwable.class, fallback, directExecutor()); derived.cancel(false); assertTrue(primary.isCancelled()); assertFalse(primary.wasInterrupted()); }
@GwtIncompatible // non-Throwable exceptionType public void testCatchingAsync_inputCancelledWithoutFallback() throws Exception { AsyncFunction<Throwable, Integer> fallback = unexpectedAsyncFunction(); ListenableFuture<Integer> originalFuture = immediateCancelledFuture(); ListenableFuture<Integer> faultTolerantFuture = catchingAsync(originalFuture, IOException.class, fallback, directExecutor()); assertTrue(faultTolerantFuture.isCancelled()); }
@GwtIncompatible // mocks // TODO(cpovirk): eliminate use of mocks @SuppressWarnings("unchecked") public void testCatchingAsync_resultCancelledAfterFallback() throws Exception { final SettableFuture<Integer> secondary = SettableFuture.create(); final RuntimeException raisedException = new RuntimeException(); AsyncFunctionSpy<Throwable, Integer> fallback = spy( new AsyncFunction<Throwable, Integer>() { @Override public ListenableFuture<Integer> apply(Throwable t) throws Exception { assertThat(t).isSameAs(raisedException); return secondary; } }); ListenableFuture<Integer> failingFuture = immediateFailedFuture(raisedException); ListenableFuture<Integer> derived = catchingAsync(failingFuture, Throwable.class, fallback, directExecutor()); derived.cancel(false); assertTrue(secondary.isCancelled()); assertFalse(secondary.wasInterrupted()); fallback.verifyCallCount(1); }