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 committed by GitHub
parent fd7260b506
commit 0956c34658
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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.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();

View File

@ -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);
}

View File

@ -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;