blob: 405772279512fa6d48af626e0f3d243aa3f26a04 [file] [log] [blame]
/*
* Copyright (C) 2011 The Guava Authors
*
* 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.
*/
package com.google.common.util.concurrent;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* A {@link Future} implementation which always throws directly from calls to {@code get()} (i.e.
* not wrapped in {@code ExecutionException}. For just a normal failure, use {@link
* SettableFuture}).
*
* <p>Useful for testing the behavior of Future utilities against odd futures.
*
* @author Anthony Zana
*/
@GwtCompatible
final class UncheckedThrowingFuture<V> extends AbstractFuture<V> {
public static <V> ListenableFuture<V> throwingError(Error error) {
UncheckedThrowingFuture<V> future = new UncheckedThrowingFuture<V>();
future.complete(checkNotNull(error));
return future;
}
public static <V> ListenableFuture<V> throwingRuntimeException(RuntimeException e) {
UncheckedThrowingFuture<V> future = new UncheckedThrowingFuture<V>();
future.complete(checkNotNull(e));
return future;
}
public static <V> UncheckedThrowingFuture<V> incomplete() {
return new UncheckedThrowingFuture<V>();
}
public void complete(RuntimeException e) {
if (!super.setException(new WrapperException(checkNotNull(e)))) {
throw new IllegalStateException("Future was already complete: " + this);
}
}
public void complete(Error e) {
if (!super.setException(new WrapperException(checkNotNull(e)))) {
throw new IllegalStateException("Future was already complete: " + this);
}
}
private static final class WrapperException extends Exception {
WrapperException(Throwable t) {
super(t);
}
}
private static void rethrow(ExecutionException e) throws ExecutionException {
Throwable wrapper = e.getCause();
if (wrapper instanceof WrapperException) {
Throwable cause = wrapper.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
}
throw e;
}
@Override
public V get() throws ExecutionException, InterruptedException {
try {
super.get();
} catch (ExecutionException e) {
rethrow(e);
}
throw new AssertionError("Unreachable");
}
@Override
public V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
try {
super.get(timeout, unit);
} catch (ExecutionException e) {
rethrow(e);
}
throw new AssertionError("Unreachable");
}
}