[
https://issues.apache.org/jira/browse/HBASE-13419?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Michael Muller updated HBASE-13419:
-----------------------------------
Status: Patch Available (was: Open)
>From 475978873c0bf0bcad5a10e371f20d8191f3f582 Mon Sep 17 00:00:00 2001
From: Michael Muller <[email protected]>
Date: Tue, 7 Apr 2015 10:57:46 -0400
Subject: [PATCH] Expand the exception causes in the thrift gateway.
Expand the full chain of exception causes when passing an error back up to a
thrift client so useful information doesn't get lost when the exception is
flattened.
---
.../hadoop/hbase/thrift/ThriftServerRunner.java | 93 +++++++++++++---------
.../hadoop/hbase/thrift/TestThriftServerUnit.java | 39 +++++++++
2 files changed, 95 insertions(+), 37 deletions(-)
create mode 100644
hbase-thrift/src/test/java/org/apache/hadoop/hbase/thrift/TestThriftServerUnit.java
diff --git
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java
index 617fab6..bf44008 100644
---
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java
+++
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift/ThriftServerRunner.java
@@ -755,7 +755,7 @@ public class ThriftServerRunner implements Runnable {
getAdmin().enableTable(getTableName(tableName));
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -765,7 +765,7 @@ public class ThriftServerRunner implements Runnable {
getAdmin().disableTable(getTableName(tableName));
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -775,7 +775,7 @@ public class ThriftServerRunner implements Runnable {
return
this.connectionCache.getAdmin().isTableEnabled(getTableName(tableName));
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -788,7 +788,7 @@ public class ThriftServerRunner implements Runnable {
((HBaseAdmin) getAdmin()).compact(getBytes(tableNameOrRegionName));
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -801,7 +801,7 @@ public class ThriftServerRunner implements Runnable {
((HBaseAdmin)
getAdmin()).majorCompact(getBytes(tableNameOrRegionName));
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -816,7 +816,7 @@ public class ThriftServerRunner implements Runnable {
return list;
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -849,7 +849,7 @@ public class ThriftServerRunner implements Runnable {
return Collections.emptyList();
} catch (IOException e){
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -894,7 +894,7 @@ public class ThriftServerRunner implements Runnable {
return ThriftUtilities.cellFromHBase(result.rawCells());
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -937,7 +937,7 @@ public class ThriftServerRunner implements Runnable {
return ThriftUtilities.cellFromHBase(result.rawCells());
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -981,7 +981,7 @@ public class ThriftServerRunner implements Runnable {
return ThriftUtilities.cellFromHBase(result.rawCells());
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1038,7 +1038,7 @@ public class ThriftServerRunner implements Runnable {
return ThriftUtilities.rowResultFromHBase(result);
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1103,7 +1103,7 @@ public class ThriftServerRunner implements Runnable {
return ThriftUtilities.rowResultFromHBase(result);
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1135,7 +1135,7 @@ public class ThriftServerRunner implements Runnable {
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1157,7 +1157,7 @@ public class ThriftServerRunner implements Runnable {
table.delete(delete);
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1178,10 +1178,10 @@ public class ThriftServerRunner implements Runnable {
getAdmin().createTable(desc);
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
} catch (IllegalArgumentException e) {
LOG.warn(e.getMessage(), e);
- throw new IllegalArgument(e.getMessage());
+ throw new IllegalArgument(expandCauses(e));
}
}
@@ -1202,7 +1202,7 @@ public class ThriftServerRunner implements Runnable {
getAdmin().deleteTable(tableName);
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1260,10 +1260,10 @@ public class ThriftServerRunner implements Runnable {
table.put(put);
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
} catch (IllegalArgumentException e) {
LOG.warn(e.getMessage(), e);
- throw new IllegalArgument(e.getMessage());
+ throw new IllegalArgument(expandCauses(e));
}
}
@@ -1331,10 +1331,10 @@ public class ThriftServerRunner implements Runnable {
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
} catch (IllegalArgumentException e) {
LOG.warn(e.getMessage(), e);
- throw new IllegalArgument(e.getMessage());
+ throw new IllegalArgument(expandCauses(e));
}
}
@@ -1360,7 +1360,7 @@ public class ThriftServerRunner implements Runnable {
getBytes(row), family, qualifier, amount);
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1396,7 +1396,7 @@ public class ThriftServerRunner implements Runnable {
}
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
return ThriftUtilities.rowResultFromHBase(results,
resultScannerWrapper.isColumnSorted());
}
@@ -1450,7 +1450,7 @@ public class ThriftServerRunner implements Runnable {
return addScanner(table.getScanner(scan), tScan.sortColumns);
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1475,7 +1475,7 @@ public class ThriftServerRunner implements Runnable {
return addScanner(table.getScanner(scan), false);
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1501,7 +1501,7 @@ public class ThriftServerRunner implements Runnable {
return addScanner(table.getScanner(scan), false);
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1531,7 +1531,7 @@ public class ThriftServerRunner implements Runnable {
return addScanner(table.getScanner(scan), false);
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1557,7 +1557,7 @@ public class ThriftServerRunner implements Runnable {
return addScanner(table.getScanner(scan), false);
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1585,7 +1585,7 @@ public class ThriftServerRunner implements Runnable {
return addScanner(table.getScanner(scan), false);
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1606,7 +1606,7 @@ public class ThriftServerRunner implements Runnable {
return columns;
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1619,7 +1619,7 @@ public class ThriftServerRunner implements Runnable {
return ThriftUtilities.cellFromHBase(result.rawCells());
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1658,7 +1658,7 @@ public class ThriftServerRunner implements Runnable {
return region;
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1696,7 +1696,7 @@ public class ThriftServerRunner implements Runnable {
table.increment(inc);
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1724,7 +1724,7 @@ public class ThriftServerRunner implements Runnable {
return ThriftUtilities.cellFromHBase(result.rawCells());
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
}
}
@@ -1745,7 +1745,7 @@ public class ThriftServerRunner implements Runnable {
put.setDurability(mput.writeToWAL ? Durability.SYNC_WAL :
Durability.SKIP_WAL);
} catch (IllegalArgumentException e) {
LOG.warn(e.getMessage(), e);
- throw new IllegalArgument(e.getMessage());
+ throw new IllegalArgument(expandCauses(e));
}
Table table = null;
@@ -1756,15 +1756,34 @@ public class ThriftServerRunner implements Runnable {
value != null ? getBytes(value) : HConstants.EMPTY_BYTE_ARRAY, put);
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
- throw new IOError(e.getMessage());
+ throw new IOError(expandCauses(e));
} catch (IllegalArgumentException e) {
LOG.warn(e.getMessage(), e);
- throw new IllegalArgument(e.getMessage());
+ throw new IllegalArgument(expandCauses(e));
}
}
}
+ /**
+ * Join all of the messages of the "cause" throwables so we don't lose
+ * root cause information.
+ */
+ protected static String expandCauses(Throwable e) {
+ StringBuilder builder = new StringBuilder();
+ while (e != null) {
+ System.out.println("Considering " + e);
+ String message = e.getMessage();
+ if (message != null) {
+ if (builder.length() > 0) {
+ builder.append(": ");
+ }
+ builder.append(message);
+ }
+ e = e.getCause();
+ }
+ return builder.toString();
+ }
/**
* Adds all the attributes into the Operation object
diff --git
a/hbase-thrift/src/test/java/org/apache/hadoop/hbase/thrift/TestThriftServerUnit.java
b/hbase-thrift/src/test/java/org/apache/hadoop/hbase/thrift/TestThriftServerUnit.java
new file mode 100644
index 0000000..29f02b2
--- /dev/null
+++
b/hbase-thrift/src/test/java/org/apache/hadoop/hbase/thrift/TestThriftServerUnit.java
@@ -0,0 +1,39 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.thrift;
+
+import org.apache.hadoop.hbase.testclassification.ClientTests;
+import org.apache.hadoop.hbase.testclassification.SmallTests;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import static org.junit.Assert.assertEquals;
+
+@Category({SmallTests.class})
+public class TestThriftServerUnit {
+ @Test
+ public void testErrorMessageExpansion() {
+ Throwable a = new Throwable("Inner");
+ Throwable b = new Throwable(a);
+ Throwable c = new Throwable("Outer", b);
+
+ assertEquals("Outer: java.lang.Throwable: Inner: Inner",
ThriftServerRunner.expandCauses(c));
+ }
+}
+
--
2.2.0.rc0.207.ga3a616c
> Thrift gateway should propagate text from exception causes.
> -----------------------------------------------------------
>
> Key: HBASE-13419
> URL: https://issues.apache.org/jira/browse/HBASE-13419
> Project: HBase
> Issue Type: Improvement
> Components: Thrift
> Reporter: Michael Muller
> Labels: newbie, patch
> Fix For: 2.0.0, 1.0.1, 1.1.0
>
>
> Exceptions passed back from the thrift gateway only include the message text
> of the toplevel exception. Information from the cause chain is lost.
> In some cases, the top-level exception text is useless but there is some very
> specific and useful information provided in some of the cause exceptions, so
> it would be very helpful to flatten all of the messages into the exception
> text returned to the user.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)