reveal underlying exception that causes a guice provider to fail

This commit is contained in:
Adrian Cole 2012-09-29 14:01:51 -07:00
parent 3695c34bd4
commit 1f4e22c6c9
5 changed files with 53 additions and 19 deletions

View File

@ -21,6 +21,7 @@ package org.jclouds.concurrent.internal;
import static com.google.common.base.Preconditions.checkState;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
@ -41,6 +42,7 @@ import org.jclouds.util.Throwables2;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
@ -158,7 +160,11 @@ public class SyncProxy implements InvocationHandler {
}
return returnVal;
} else if (syncMethodMap.containsKey(method)) {
return syncMethodMap.get(method).invoke(delegate, args);
try {
return syncMethodMap.get(method).invoke(delegate, args);
} catch (InvocationTargetException e) {
throw Throwables.propagate(e.getCause());
}
} else {
try {
return ((ListenableFuture<?>) methodMap.get(method).invoke(delegate, args)).get(timeoutMap.get(method),

View File

@ -18,6 +18,7 @@
*/
package org.jclouds.location.suppliers.derived;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.URI;
import java.util.Map;
import java.util.Set;
@ -28,6 +29,7 @@ import org.jclouds.location.Region;
import org.jclouds.location.suppliers.RegionIdsSupplier;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.inject.Inject;
/**
@ -45,6 +47,10 @@ public class RegionIdsFromRegionIdToURIKeySet implements RegionIdsSupplier {
@Override
public Set<String> get() {
return regionIdToURISupplier.get().keySet();
try {
return regionIdToURISupplier.get().keySet();
} catch (UndeclaredThrowableException e) {
throw Throwables.propagate(e.getCause());
}
}
}

View File

@ -22,7 +22,6 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.NoSuchElementException;
import java.util.concurrent.ExecutionException;
import javax.annotation.Resource;
@ -49,12 +48,14 @@ import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.Binding;
import com.google.inject.ConfigurationException;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
@ -176,8 +177,10 @@ public class AsyncRestClientProxy<T> implements InvocationHandler {
try {
Annotation qualifier = Iterables.find(ImmutableList.copyOf(method.getAnnotations()), isQualifierPresent);
return getInstanceOfTypeWithQualifier(genericReturnType, qualifier);
} catch (NoSuchElementException e) {
return getInstanceOfType(genericReturnType);
} catch (ProvisionException e) {
throw Throwables.propagate(e.getCause());
} catch (RuntimeException e) {
return instanceOfTypeOrPropagate(genericReturnType, e);
}
} catch (ProvisionException e) {
AuthorizationException aex = Throwables2.getFirstThrowableOfType(e, AuthorizationException.class);
@ -188,19 +191,23 @@ public class AsyncRestClientProxy<T> implements InvocationHandler {
}
// TODO: tidy
private Object getInstanceOfType(Type genericReturnType) {
// look for an existing binding
Binding<?> binding = injector.getExistingBinding(Key.get(genericReturnType));
if (binding != null)
return binding.getProvider().get();
private Object instanceOfTypeOrPropagate(Type genericReturnType, RuntimeException e) {
try {
// look for an existing binding
Binding<?> binding = injector.getExistingBinding(Key.get(genericReturnType));
if (binding != null)
return binding.getProvider().get();
// then, try looking via supplier
binding = injector.getExistingBinding(Key.get(Types.newParameterizedType(Supplier.class, genericReturnType)));
if (binding != null)
return Supplier.class.cast(binding.getProvider().get()).get();
// then, try looking via supplier
binding = injector.getExistingBinding(Key.get(Types.newParameterizedType(Supplier.class, genericReturnType)));
if (binding != null)
return Supplier.class.cast(binding.getProvider().get()).get();
// else try to create an instance
return injector.getInstance(Key.get(genericReturnType));
// else try to create an instance
return injector.getInstance(Key.get(genericReturnType));
} catch (ConfigurationException ce) {
throw e;
}
}
// TODO: tidy

View File

@ -73,7 +73,6 @@ import org.jclouds.providers.ProviderMetadata;
import org.jclouds.rest.RestApiMetadata;
import org.jclouds.rest.config.CredentialStoreModule;
import org.jclouds.util.Strings2;
import org.testng.annotations.Test;
import org.w3c.dom.Node;
import com.google.common.annotations.Beta;

View File

@ -43,6 +43,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@ -2476,6 +2477,10 @@ public class RestAnnotationProcessorTest extends BaseRestApiTest {
@Provides
Set<String> exception();
@Named("NoSuchElementException")
@Provides
Set<String> noSuchElementException();
@POST
@Path("/")
void oneForm(@PathParam("bucket") String path);
@ -2497,7 +2502,12 @@ public class RestAnnotationProcessorTest extends BaseRestApiTest {
public void testProvidesWithGenericQualifiedAuthorizationException() throws SecurityException, NoSuchMethodException {
injector.getInstance(AsyncClientFactory.class).create(TestClassForm.class).exception();
}
@Test(expectedExceptions = NoSuchElementException.class)
public void testProvidesWithGenericQualifiedNoSuchElementException() throws SecurityException, NoSuchMethodException {
injector.getInstance(AsyncClientFactory.class).create(TestClassForm.class).noSuchElementException();
}
@Test
public void testBuildOneClassForm() throws SecurityException, NoSuchMethodException {
Method oneForm = TestClassForm.class.getMethod("oneForm", String.class);
@ -2664,7 +2674,13 @@ public class RestAnnotationProcessorTest extends BaseRestApiTest {
Set<String> exception() {
throw new AuthorizationException();
}
@Provides
@Named("NoSuchElementException")
Set<String> noSuchElementException() {
throw new NoSuchElementException();
}
})).buildInjector();
parserFactory = injector.getInstance(ParseSax.Factory.class);
crypto = injector.getInstance(Crypto.class);