Merge branch 'master' into yingyi/asterix_beta_fix
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/APIServlet.java b/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/APIServlet.java
index e729742..b5d15d2 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/APIServlet.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/APIServlet.java
@@ -33,6 +33,7 @@
 import edu.uci.ics.asterix.common.config.GlobalConfig;
 import edu.uci.ics.asterix.metadata.MetadataManager;
 import edu.uci.ics.asterix.result.ResultReader;
+import edu.uci.ics.asterix.result.ResultUtils;
 import edu.uci.ics.hyracks.api.client.IHyracksClientConnection;
 import edu.uci.ics.hyracks.api.dataset.IHyracksDataset;
 import edu.uci.ics.hyracks.client.dataset.HyracksDataset;
@@ -109,9 +110,10 @@
             }
             out.println("</pre>");
         } catch (Exception e) {
-            GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, e.getMessage(), e);
+            String errorMessage = ResultUtils.extractErrorMessage(e);
+            GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, errorMessage, e);
             out.println("<pre class=\"error\">");
-            out.println(e.getMessage());
+            out.println(errorMessage);
             out.println("</pre>");
         }
     }
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/RESTAPIServlet.java b/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/RESTAPIServlet.java
index 2cfa59e..b5196ec 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/RESTAPIServlet.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/RESTAPIServlet.java
@@ -107,9 +107,8 @@
             aqlTranslator.compileAndExecute(hcc, hds, asyncResults);
 
         } catch (ParseException pe) {
-            GlobalConfig.ASTERIX_LOGGER.log(Level.INFO, pe.getMessage(), pe);
             StringBuilder errorMessage = new StringBuilder();
-            String message = pe.getMessage();
+            String message = pe.getLocalizedMessage();
             message = message.replace("<", "&lt");
             message = message.replace(">", "&gt");
             errorMessage.append("SyntaxError:" + message + "\n");
@@ -123,10 +122,9 @@
             JSONObject errorResp = ResultUtils.getErrorResponse(2, errorMessage.toString());
             out.write(errorResp.toString());
         } catch (Exception e) {
-            GlobalConfig.ASTERIX_LOGGER.log(Level.INFO, e.getMessage(), e);
-            StringBuilder errorMessage = new StringBuilder();
-            errorMessage.append(e.getMessage());
-            JSONObject errorResp = ResultUtils.getErrorResponse(99, errorMessage.toString());
+            String errorMessage = ResultUtils.extractErrorMessage(e);
+            GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, errorMessage, e);
+            JSONObject errorResp = ResultUtils.getErrorResponse(99, errorMessage);
             out.write(errorResp.toString());
         }
     }
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/result/ResultUtils.java b/asterix-app/src/main/java/edu/uci/ics/asterix/result/ResultUtils.java
index dec3128..4d62e3f 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/result/ResultUtils.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/result/ResultUtils.java
@@ -79,4 +79,26 @@
             // TODO(madhusudancs): Figure out what to do when JSONException occurs while building the results.
         }
     }
+
+    /**
+     * extract meaningful part of a stack trace:
+     * a. the causes in the stack trace hierarchy
+     * b. the top exception for each cause
+     * 
+     * @param e
+     * @return the contacted message containing a and b.
+     */
+    public static String extractErrorMessage(Throwable e) {
+        StringBuilder errorMessageBuilder = new StringBuilder();
+        Throwable cause = e;
+        while (cause != null) {
+            StackTraceElement[] stackTraceElements = e.getStackTrace();
+            errorMessageBuilder.append(cause.toString());
+            errorMessageBuilder.append(stackTraceElements.length > 0 ? "\n at " + stackTraceElements[0] : "");
+            errorMessageBuilder.append("\n");
+            cause = cause.getCause();
+        }
+        String errorMessage = errorMessageBuilder.toString();
+        return errorMessage;
+    }
 }
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/query-issue355/query-issue355.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/query-issue355/query-issue355.1.ddl.aql
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/query-issue355/query-issue355.1.ddl.aql
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/query-issue355/query-issue355.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/query-issue355/query-issue355.2.update.aql
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/query-issue355/query-issue355.2.update.aql
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/query-issue355/query-issue355.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/query-issue355/query-issue355.3.query.aql
new file mode 100644
index 0000000..599bc16
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/query-issue355/query-issue355.3.query.aql
@@ -0,0 +1,3 @@
+for $a in [{"name":"Bob","age":10,"sex":"Male"},{"name":"John","age":45,"sex":"Female"},{"name":"Raj","age":35,"sex":"Male"}]
+where string-length($a.name) > -10000000000000000000
+return [$a.age, string-equal(lowercase($a.name), "john")]
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/query-issue355/query-issue355.1.adm b/asterix-app/src/test/resources/runtimets/results/numeric/query-issue355/query-issue355.1.adm
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/query-issue355/query-issue355.1.adm
@@ -0,0 +1 @@
+
diff --git a/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index 9e6c308..e0607ac 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -2554,6 +2554,12 @@
         <output-dir compare="Text">unary-minus_null</output-dir>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="numeric">
+      <compilation-unit name="query-issue355">
+        <output-dir compare="Text">query-issue355</output-dir>
+        <expected-error>edu.uci.ics.asterix.common.exceptions.AsterixException</expected-error>
+      </compilation-unit>
+    </test-case>
   </test-group>
   <test-group name="open-closed">
     <!--
diff --git a/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java b/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
index 79ab067..acb1e6a 100644
--- a/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
+++ b/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
@@ -359,10 +359,8 @@
                             break;
                         case "query":
                             result = TestsUtils.executeQuery(statement);
-                            if (!cUnit.getExpectedError().isEmpty()) {
-                                if (!result.has("error")) {
-                                    throw new Exception("Test \"" + testFile + "\" FAILED!");
-                                }
+                            if (result.has("error-code")) {
+                                throw new Exception("Test \"" + testFile + "\" FAILED!\n" + result + "\n");
                             } else {
                                 expectedResultFile = expectedResultFileCtxs.get(queryCount).getFile();