diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncTableResultScanner.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncTableResultScanner.java index cd5d5adb290..7fe6d120c3f 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncTableResultScanner.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncTableResultScanner.java @@ -23,13 +23,13 @@ import java.io.IOException; import java.io.InterruptedIOException; import java.util.ArrayDeque; import java.util.Queue; - +import org.apache.hadoop.hbase.client.metrics.ScanMetrics; +import org.apache.hadoop.hbase.util.FutureUtils; import org.apache.yetus.audience.InterfaceAudience; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.hadoop.hbase.client.metrics.ScanMetrics; + import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; -import org.apache.hbase.thirdparty.com.google.common.base.Throwables; /** * The {@link ResultScanner} implementation for {@link AsyncTable}. It will fetch data automatically @@ -140,8 +140,7 @@ class AsyncTableResultScanner implements ResultScanner, AdvancedScanResultConsum return null; } if (error != null) { - Throwables.propagateIfPossible(error, IOException.class); - throw new IOException(error); + FutureUtils.rethrow(error); } try { wait(); diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/FutureUtils.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/FutureUtils.java index dfd9ead2785..67a7d84b26f 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/FutureUtils.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/FutureUtils.java @@ -139,19 +139,23 @@ public final class FutureUtils { error.setStackTrace(newStackTrace); } - private static IOException rethrow(ExecutionException error) throws IOException { - Throwable cause = error.getCause(); - if (cause instanceof IOException) { - setStackTrace(cause); - throw (IOException) cause; - } else if (cause instanceof RuntimeException) { - setStackTrace(cause); - throw (RuntimeException) cause; - } else if (cause instanceof Error) { - setStackTrace(cause); - throw (Error) cause; + /** + * If we could propagate the given {@code error} directly, we will fill the stack trace with the + * current thread's stack trace so it is easier to trace where is the exception thrown. If not, we + * will just create a new IOException and then throw it. + */ + public static IOException rethrow(Throwable error) throws IOException { + if (error instanceof IOException) { + setStackTrace(error); + throw (IOException) error; + } else if (error instanceof RuntimeException) { + setStackTrace(error); + throw (RuntimeException) error; + } else if (error instanceof Error) { + setStackTrace(error); + throw (Error) error; } else { - throw new IOException(cause); + throw new IOException(error); } } @@ -165,7 +169,7 @@ public final class FutureUtils { } catch (InterruptedException e) { throw (IOException) new InterruptedIOException().initCause(e); } catch (ExecutionException e) { - throw rethrow(e); + throw rethrow(e.getCause()); } } @@ -179,7 +183,7 @@ public final class FutureUtils { } catch (InterruptedException e) { throw (IOException) new InterruptedIOException().initCause(e); } catch (ExecutionException e) { - throw rethrow(e); + throw rethrow(e.getCause()); } catch (TimeoutException e) { throw new TimeoutIOException(e); } diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestFutureUtils.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestFutureUtils.java index 0eef0a6fc51..f09d9473972 100644 --- a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestFutureUtils.java +++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestFutureUtils.java @@ -19,8 +19,8 @@ package org.apache.hadoop.hbase.util; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.startsWith; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail;