Update the API result framework to include 3 levels of details.
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 d1b2d5f..c5d0e57 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
@@ -17,6 +17,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.List;
+import java.util.logging.Level;
 
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServlet;
@@ -33,6 +34,7 @@
 import edu.uci.ics.asterix.aql.parser.ParseException;
 import edu.uci.ics.asterix.aql.parser.TokenMgrError;
 import edu.uci.ics.asterix.aql.translator.AqlTranslator;
+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;
@@ -95,10 +97,12 @@
 
             aqlTranslator.compileAndExecute(hcc, hds, asyncResults);
         } catch (ParseException | TokenMgrError | edu.uci.ics.asterix.aqlplus.parser.TokenMgrError pe) {
+            GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, pe.getMessage(), pe);
             String errorMessage = ResultUtils.buildParseExceptionMessage(pe, query);
-            JSONObject errorResp = ResultUtils.getErrorResponse(2, errorMessage);
+            JSONObject errorResp = ResultUtils.getErrorResponse(2, errorMessage, "", "");
             out.write(errorResp.toString());
         } catch (Exception e) {
+            GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, e.getMessage(), e);
             ResultUtils.apiErrorHandler(out, e);
         }
     }
@@ -106,7 +110,8 @@
     private boolean checkForbiddenStatements(List<Statement> aqlStatements, PrintWriter out) {
         for (Statement st : aqlStatements) {
             if (!getAllowedStatements().contains(st.getKind())) {
-                JSONObject errorResp = ResultUtils.getErrorResponse(1, String.format(getErrorMessage(), st.getKind()));
+                JSONObject errorResp = ResultUtils.getErrorResponse(1, String.format(getErrorMessage(), st.getKind()),
+                        "", "");
                 out.write(errorResp.toString());
                 return true;
             }
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 8fd65f3..44a54e0 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
@@ -21,7 +21,6 @@
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.nio.ByteBuffer;
-import java.util.logging.Level;
 
 import org.json.JSONArray;
 import org.json.JSONException;
@@ -30,7 +29,6 @@
 import com.sun.el.parser.ParseException;
 
 import edu.uci.ics.asterix.api.http.servlet.APIServlet;
-import edu.uci.ics.asterix.common.config.GlobalConfig;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.api.comm.IFrameTupleAccessor;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
@@ -61,13 +59,18 @@
         return resultRecords;
     }
 
-    public static JSONObject getErrorResponse(int errorCode, String errorMessage) {
+    public static JSONObject getErrorResponse(int errorCode, String errorMessage, String errorSummary,
+            String errorStackTrace) {
         JSONObject errorResp = new JSONObject();
         JSONArray errorArray = new JSONArray();
         errorArray.put(errorCode);
         errorArray.put(errorMessage);
         try {
             errorResp.put("error-code", errorArray);
+            if (!errorSummary.equals(""))
+                errorResp.put("summary", errorSummary);
+            if (!errorStackTrace.equals(""))
+                errorResp.put("stacktrace", errorStackTrace);
         } catch (JSONException e) {
             // TODO(madhusudancs): Figure out what to do when JSONException occurs while building the results.
         }
@@ -111,21 +114,16 @@
 
     public static void apiErrorHandler(PrintWriter out, Exception e) {
         int errorCode = 99;
-        String errPrefix = "";
         if (e instanceof ParseException) {
             errorCode = 2;
         } else if (e instanceof AlgebricksException) {
             errorCode = 3;
-            errPrefix = "Compilation error: ";
         } else if (e instanceof HyracksDataException) {
             errorCode = 4;
-            errPrefix = "Runtime error: ";
         }
 
-        Throwable cause = getRootCause(e);
-
-        GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, e.getMessage(), e);
-        JSONObject errorResp = ResultUtils.getErrorResponse(errorCode, errPrefix + cause.getMessage());
+        JSONObject errorResp = ResultUtils.getErrorResponse(errorCode, extractErrorMessage(e), extractErrorSummary(e),
+                extractFullStackTrace(e));
         out.write(errorResp.toString());
     }