HADOOP-13857. S3AUtils.translateException to map (wrapped) InterruptedExceptions to InterruptedIOEs. Contributed by Steve Loughran

This commit is contained in:
Mingliang Liu 2016-12-02 13:36:04 -08:00
parent c7ff34f8dc
commit 2ff84a0040
2 changed files with 61 additions and 0 deletions

View File

@ -40,6 +40,7 @@ import org.slf4j.Logger;
import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@ -113,6 +114,10 @@ public final class S3AUtils {
path != null ? (" on " + path) : "",
exception);
if (!(exception instanceof AmazonServiceException)) {
if (containsInterruptedException(exception)) {
return (IOException)new InterruptedIOException(message)
.initCause(exception);
}
return new AWSClientIOException(message, exception);
} else {
@ -194,6 +199,24 @@ public final class S3AUtils {
return ioe;
}
/**
* Recurse down the exception loop looking for any inner details about
* an interrupted exception.
* @param thrown exception thrown
* @return true if down the execution chain the operation was an interrupt
*/
static boolean containsInterruptedException(Throwable thrown) {
if (thrown == null) {
return false;
}
if (thrown instanceof InterruptedException ||
thrown instanceof InterruptedIOException) {
return true;
}
// tail recurse
return containsInterruptedException(thrown.getCause());
}
/**
* Get low level details of an amazon exception for logging; multi-line.
* @param e exception

View File

@ -25,9 +25,12 @@ import static org.junit.Assert.*;
import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.nio.file.AccessDeniedException;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
@ -124,4 +127,39 @@ public class TestS3AExceptionTranslation {
return verifyExceptionClass(clazz,
translateException("test", "/", exception));
}
private void assertContainsInterrupted(boolean expected, Throwable thrown)
throws Throwable {
if (containsInterruptedException(thrown) != expected) {
throw thrown;
}
}
@Test
public void testInterruptExceptionDetecting() throws Throwable {
InterruptedException interrupted = new InterruptedException("irq");
assertContainsInterrupted(true, interrupted);
IOException ioe = new IOException("ioe");
assertContainsInterrupted(false, ioe);
assertContainsInterrupted(true, ioe.initCause(interrupted));
assertContainsInterrupted(true,
new InterruptedIOException("ioirq"));
}
@Test(expected = InterruptedIOException.class)
public void testExtractInterrupted() throws Throwable {
throw extractException("", "",
new ExecutionException(
new AmazonClientException(
new InterruptedException(""))));
}
@Test(expected = InterruptedIOException.class)
public void testExtractInterruptedIO() throws Throwable {
throw extractException("", "",
new ExecutionException(
new AmazonClientException(
new InterruptedIOException(""))));
}
}