package org.dcache.chimera.nfsv41.door;
import com.google.common.base.Throwables;
import diskCacheV111.util.CacheException;
import java.lang.reflect.InvocationTargetException;
import org.dcache.nfs.ChimeraNFSException;
import org.dcache.nfs.status.*;
import static diskCacheV111.util.CacheException.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
/**
* Utility class to convert {@link CacheException} into corresponding
* {@link ChimeraNFSException}.
*/
public class ExceptionUtils {
private ExceptionUtils() {
}
/**
* Converts given {@link Throwable} into appropriate {@link ChimeraNFSException}
* if and only if it is not an instance of {@link RuntimeException} or {@link Error}.
* If appropriate exception is not found, then an instance of {@code defaultException} is returned.
*
* @param t the Throwable to convert
* @param defaultException
* @return appropriate nfs exception
*/
public static ChimeraNFSException asNfsException(Throwable t, Class< ? extends ChimeraNFSException> defaultException) {
Throwables.throwIfUnchecked(t);
if (t instanceof ChimeraNFSException) {
return (ChimeraNFSException)t;
} else if (t instanceof CacheException) {
return asNfsException((CacheException)t, defaultException);
} else if (t instanceof ExecutionException ) {
return asNfsException(t.getCause(), defaultException);
} else if (t instanceof TimeoutException) {
return new DelayException(t.getMessage(), t);
} else if (t instanceof RuntimeException) {
return new ServerFaultException(t.getMessage(), t);
} else {
return buildNfsException(defaultException, t);
}
}
public static ChimeraNFSException asNfsException(CacheException e, Class< ? extends ChimeraNFSException> defaultException) {
switch (e.getRc()) {
case BROKEN_ON_TAPE:
case ERROR_IO_DISK:
return new NfsIoException(e.getMessage(), e);
case FILE_NOT_FOUND:
return new NoEntException(e.getMessage(), e);
case NO_POOL_ONLINE:
return new LayoutTryLaterException(e.getMessage(), e);
case PERMISSION_DENIED:
return new PermException(e.getMessage(), e);
case NO_POOL_CONFIGURED:
return new NoSpcException(e.getMessage(), e);
case TIMEOUT:
return new DelayException(e.getMessage(), e);
case FILE_IN_CACHE:
return new NfsIoException(e.getMessage(), e);
default:
return buildNfsException(defaultException, e);
}
}
private static <T extends ChimeraNFSException> T buildNfsException(Class<T> type, Throwable cause) {
try {
return type
.getConstructor(String.class, Throwable.class)
.newInstance(cause.getMessage(), cause);
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException ee) {
// points to a bug
throw new RuntimeException("Failed to invoke constructor", ee);
}
}
}