HBASE-25066 Use FutureUtils.rethrow in AsyncTableResultScanner to better catch the stack trace (#2420)

Signed-off-by: Guanghao Zhang <zghao@apache.org>
This commit is contained in:
Duo Zhang 2020-09-20 11:25:22 +08:00
parent bc9921627a
commit fe03a35ea2
3 changed files with 23 additions and 20 deletions

View File

@ -23,13 +23,13 @@ import java.io.IOException;
import java.io.InterruptedIOException; import java.io.InterruptedIOException;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Queue; 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.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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.annotations.VisibleForTesting;
import org.apache.hbase.thirdparty.com.google.common.base.Throwables;
/** /**
* The {@link ResultScanner} implementation for {@link AsyncTable}. It will fetch data automatically * The {@link ResultScanner} implementation for {@link AsyncTable}. It will fetch data automatically
@ -140,8 +140,7 @@ class AsyncTableResultScanner implements ResultScanner, AdvancedScanResultConsum
return null; return null;
} }
if (error != null) { if (error != null) {
Throwables.propagateIfPossible(error, IOException.class); FutureUtils.rethrow(error);
throw new IOException(error);
} }
try { try {
wait(); wait();

View File

@ -139,19 +139,23 @@ public final class FutureUtils {
error.setStackTrace(newStackTrace); error.setStackTrace(newStackTrace);
} }
private static IOException rethrow(ExecutionException error) throws IOException { /**
Throwable cause = error.getCause(); * If we could propagate the given {@code error} directly, we will fill the stack trace with the
if (cause instanceof IOException) { * current thread's stack trace so it is easier to trace where is the exception thrown. If not, we
setStackTrace(cause); * will just create a new IOException and then throw it.
throw (IOException) cause; */
} else if (cause instanceof RuntimeException) { public static IOException rethrow(Throwable error) throws IOException {
setStackTrace(cause); if (error instanceof IOException) {
throw (RuntimeException) cause; setStackTrace(error);
} else if (cause instanceof Error) { throw (IOException) error;
setStackTrace(cause); } else if (error instanceof RuntimeException) {
throw (Error) cause; setStackTrace(error);
throw (RuntimeException) error;
} else if (error instanceof Error) {
setStackTrace(error);
throw (Error) error;
} else { } else {
throw new IOException(cause); throw new IOException(error);
} }
} }
@ -165,7 +169,7 @@ public final class FutureUtils {
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw (IOException) new InterruptedIOException().initCause(e); throw (IOException) new InterruptedIOException().initCause(e);
} catch (ExecutionException e) { } catch (ExecutionException e) {
throw rethrow(e); throw rethrow(e.getCause());
} }
} }
@ -179,7 +183,7 @@ public final class FutureUtils {
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw (IOException) new InterruptedIOException().initCause(e); throw (IOException) new InterruptedIOException().initCause(e);
} catch (ExecutionException e) { } catch (ExecutionException e) {
throw rethrow(e); throw rethrow(e.getCause());
} catch (TimeoutException e) { } catch (TimeoutException e) {
throw new TimeoutIOException(e); throw new TimeoutIOException(e);
} }

View File

@ -19,8 +19,8 @@ package org.apache.hadoop.hbase.util;
import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.startsWith; import static org.hamcrest.CoreMatchers.startsWith;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;