fixed exception parsing to return the correct parent exception

This commit is contained in:
Adrian Cole 2010-07-20 16:24:39 -07:00
parent 89ae22364c
commit becf96d822
1 changed files with 18 additions and 17 deletions

View File

@ -35,6 +35,8 @@ import javax.inject.Named;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.internal.ClassMethodArgs; import org.jclouds.internal.ClassMethodArgs;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
import org.jclouds.util.Utils; import org.jclouds.util.Utils;
@ -52,8 +54,8 @@ import com.google.common.util.concurrent.ListenableFuture;
public class SyncProxy implements InvocationHandler { public class SyncProxy implements InvocationHandler {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T proxy(Class<T> clazz, SyncProxy proxy) throws IllegalArgumentException, public static <T> T proxy(Class<T> clazz, SyncProxy proxy) throws IllegalArgumentException, SecurityException,
SecurityException, NoSuchMethodException { NoSuchMethodException {
return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[] { clazz }, proxy); return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[] { clazz }, proxy);
} }
@ -68,15 +70,14 @@ public class SyncProxy implements InvocationHandler {
@Inject @Inject
public SyncProxy(Class<?> declaring, Object async, public SyncProxy(Class<?> declaring, Object async,
@Named("sync") ConcurrentMap<ClassMethodArgs, Object> delegateMap, @Named("sync") ConcurrentMap<ClassMethodArgs, Object> delegateMap, Map<Class<?>, Class<?>> sync2Async)
Map<Class<?>, Class<?>> sync2Async) throws SecurityException, NoSuchMethodException { throws SecurityException, NoSuchMethodException {
this.delegateMap = delegateMap; this.delegateMap = delegateMap;
this.delegate = async; this.delegate = async;
this.declaring = declaring; this.declaring = declaring;
this.sync2Async = sync2Async; this.sync2Async = sync2Async;
if (!declaring.isAnnotationPresent(Timeout.class)) { if (!declaring.isAnnotationPresent(Timeout.class)) {
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format("type %s does not specify a default @Timeout", declaring));
"type %s does not specify a default @Timeout", declaring));
} }
Timeout typeTimeout = declaring.getAnnotation(Timeout.class); Timeout typeTimeout = declaring.getAnnotation(Timeout.class);
long typeNanos = convertToNanos(typeTimeout); long typeNanos = convertToNanos(typeTimeout);
@ -86,12 +87,10 @@ public class SyncProxy implements InvocationHandler {
timeoutMap = Maps.newHashMap(); timeoutMap = Maps.newHashMap();
for (Method method : declaring.getMethods()) { for (Method method : declaring.getMethods()) {
if (!objectMethods.contains(method)) { if (!objectMethods.contains(method)) {
Method delegatedMethod = delegate.getClass().getMethod(method.getName(), Method delegatedMethod = delegate.getClass().getMethod(method.getName(), method.getParameterTypes());
method.getParameterTypes());
if (!Arrays.equals(delegatedMethod.getExceptionTypes(), method.getExceptionTypes())) if (!Arrays.equals(delegatedMethod.getExceptionTypes(), method.getExceptionTypes()))
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format(
"method %s has different typed exceptions than delegated method %s", "method %s has different typed exceptions than delegated method %s", method, delegatedMethod));
method, delegatedMethod));
if (delegatedMethod.getReturnType().isAssignableFrom(ListenableFuture.class)) { if (delegatedMethod.getReturnType().isAssignableFrom(ListenableFuture.class)) {
if (method.isAnnotationPresent(Timeout.class)) { if (method.isAnnotationPresent(Timeout.class)) {
Timeout methodTimeout = method.getAnnotation(Timeout.class); Timeout methodTimeout = method.getAnnotation(Timeout.class);
@ -122,16 +121,16 @@ public class SyncProxy implements InvocationHandler {
return this.toString(); return this.toString();
} else if (method.isAnnotationPresent(Delegate.class)) { } else if (method.isAnnotationPresent(Delegate.class)) {
Class<?> asyncClass = sync2Async.get(method.getReturnType()); Class<?> asyncClass = sync2Async.get(method.getReturnType());
checkState(asyncClass != null, "please configure corresponding async class for " checkState(asyncClass != null, "please configure corresponding async class for " + method.getReturnType()
+ method.getReturnType() + " in your RestClientModule"); + " in your RestClientModule");
Object returnVal = delegateMap.get(new ClassMethodArgs(asyncClass, method, args)); Object returnVal = delegateMap.get(new ClassMethodArgs(asyncClass, method, args));
return returnVal; return returnVal;
} else if (syncMethodMap.containsKey(method)) { } else if (syncMethodMap.containsKey(method)) {
return syncMethodMap.get(method).invoke(delegate, args); return syncMethodMap.get(method).invoke(delegate, args);
} else { } else {
try { try {
return ((ListenableFuture<?>) methodMap.get(method).invoke(delegate, args)).get( return ((ListenableFuture<?>) methodMap.get(method).invoke(delegate, args)).get(timeoutMap.get(method),
timeoutMap.get(method), TimeUnit.NANOSECONDS); TimeUnit.NANOSECONDS);
} catch (ExecutionException e) { } catch (ExecutionException e) {
throw throwTypedExceptionOrCause(method.getExceptionTypes(), e); throw throwTypedExceptionOrCause(method.getExceptionTypes(), e);
} catch (Exception e) { } catch (Exception e) {
@ -141,14 +140,16 @@ public class SyncProxy implements InvocationHandler {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static Exception throwTypedExceptionOrCause(Class[] exceptionTypes, Exception exception) public static Exception throwTypedExceptionOrCause(Class[] exceptionTypes, Exception exception) throws Exception {
throws Exception {
for (Class type : exceptionTypes) { for (Class type : exceptionTypes) {
Throwable throwable = Utils.getFirstThrowableOfType(exception, type); Throwable throwable = Utils.getFirstThrowableOfType(exception, type);
if (throwable != null) { if (throwable != null) {
Throwables.throwCause(exception, true); return (Exception) throwable;
} }
} }
Throwables.propagateIfInstanceOf(exception, IllegalStateException.class);
Throwables.propagateIfInstanceOf(exception, AuthorizationException.class);
Throwables.propagateIfInstanceOf(exception, ResourceNotFoundException.class);
Throwables.throwCause(exception, true); Throwables.throwCause(exception, true);
return exception; return exception;
} }