Merge branch 'eugenia/web_ui_beta_fixes' into madhusudancs/error-reporting
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 c7954d8..fcea1ea 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
@@ -89,29 +89,12 @@
} catch (ParseException | TokenMgrError | edu.uci.ics.asterix.aqlplus.parser.TokenMgrError pe) {
GlobalConfig.ASTERIX_LOGGER.log(Level.INFO, pe.toString(), pe);
out.println("<pre class=\"error\">");
- String message = pe.getMessage();
- message = message.replace("<", "<");
- message = message.replace(">", ">");
- out.println("SyntaxError:" + message);
- int pos = message.indexOf("line");
- if (pos > 0) {
- int columnPos = message.indexOf(",", pos + 1 + "line".length());
- int lineNo = Integer.parseInt(message.substring(pos + "line".length() + 1, columnPos));
- String[] lines = query.split("\n");
- if (lineNo >= lines.length) {
- out.println("===> <BLANK LINE>");
- } else {
- String line = lines[lineNo - 1];
- out.println("==> " + line);
- }
- }
- out.println("</pre>");
- } catch (Exception e) {
- String errorMessage = ResultUtils.extractErrorMessage(e);
- GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, errorMessage, e);
- out.println("<pre class=\"error\">");
+ String errorMessage = ResultUtils.buildParseExceptionMessage(pe, query);
out.println(errorMessage);
out.println("</pre>");
+ } catch (Exception e) {
+ GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, e.getMessage(), e);
+ ResultUtils.webUIErrorHandler(out, e);
}
}
@@ -126,7 +109,7 @@
} else {
resourcePath = requestURI;
}
-
+
InputStream is = APIServlet.class.getResourceAsStream(resourcePath);
if (is == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
@@ -134,18 +117,18 @@
}
// Special handler for font files and .png resources
- if (resourcePath.endsWith(".png")) {
-
+ if (resourcePath.endsWith(".png")) {
+
BufferedImage img = ImageIO.read(is);
OutputStream outputStream = response.getOutputStream();
- String formatName = "png";
+ String formatName = "png";
response.setContentType("image/png");
ImageIO.write(img, formatName, outputStream);
outputStream.close();
return;
}
-
+
response.setCharacterEncoding("utf-8");
InputStreamReader isr = new InputStreamReader(is);
StringBuilder sb = new StringBuilder();
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 dff759d..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
@@ -32,6 +32,7 @@
import edu.uci.ics.asterix.aql.base.Statement.Kind;
import edu.uci.ics.asterix.aql.parser.AQLParser;
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;
@@ -95,35 +96,22 @@
AqlTranslator aqlTranslator = new AqlTranslator(aqlStatements, out, sessionConfig, format);
aqlTranslator.compileAndExecute(hcc, hds, asyncResults);
-
- } catch (ParseException pe) {
- GlobalConfig.ASTERIX_LOGGER.log(Level.INFO, pe.toString(), pe);
- StringBuilder errorMessage = new StringBuilder();
- String message = pe.getLocalizedMessage();
- message = message.replace("<", "<");
- message = message.replace(">", ">");
- errorMessage.append("SyntaxError:" + message + "\n");
- int pos = message.indexOf("line");
- if (pos > 0) {
- int columnPos = message.indexOf(",", pos + 1 + "line".length());
- int lineNo = Integer.parseInt(message.substring(pos + "line".length() + 1, columnPos));
- String line = query.split("\n")[lineNo - 1];
- errorMessage.append("==> " + line + "\n");
- }
- JSONObject errorResp = ResultUtils.getErrorResponse(2, errorMessage.toString());
+ } 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, "", "");
out.write(errorResp.toString());
} catch (Exception e) {
- String errorMessage = ResultUtils.extractErrorMessage(e);
- GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, errorMessage, e);
- JSONObject errorResp = ResultUtils.getErrorResponse(99, errorMessage);
- out.write(errorResp.toString());
+ GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, e.getMessage(), e);
+ ResultUtils.apiErrorHandler(out, e);
}
}
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/aql/translator/AqlTranslator.java b/asterix-app/src/main/java/edu/uci/ics/asterix/aql/translator/AqlTranslator.java
index 41be278..93dcf39 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/aql/translator/AqlTranslator.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/aql/translator/AqlTranslator.java
@@ -186,112 +186,107 @@
metadataProvider.setOutputFile(outputFile);
metadataProvider.setConfig(config);
jobsToExecute.clear();
- try {
- switch (stmt.getKind()) {
- case SET: {
- handleSetStatement(metadataProvider, stmt, config);
- break;
- }
- case DATAVERSE_DECL: {
- activeDefaultDataverse = handleUseDataverseStatement(metadataProvider, stmt);
- break;
- }
- case CREATE_DATAVERSE: {
- handleCreateDataverseStatement(metadataProvider, stmt);
- break;
- }
- case DATASET_DECL: {
- handleCreateDatasetStatement(metadataProvider, stmt, hcc);
- break;
- }
- case CREATE_INDEX: {
- handleCreateIndexStatement(metadataProvider, stmt, hcc);
- break;
- }
- case TYPE_DECL: {
- handleCreateTypeStatement(metadataProvider, stmt);
- break;
- }
- case NODEGROUP_DECL: {
- handleCreateNodeGroupStatement(metadataProvider, stmt);
- break;
- }
- case DATAVERSE_DROP: {
- handleDataverseDropStatement(metadataProvider, stmt, hcc);
- break;
- }
- case DATASET_DROP: {
- handleDatasetDropStatement(metadataProvider, stmt, hcc);
- break;
- }
- case INDEX_DROP: {
- handleIndexDropStatement(metadataProvider, stmt, hcc);
- break;
- }
- case TYPE_DROP: {
- handleTypeDropStatement(metadataProvider, stmt);
- break;
- }
- case NODEGROUP_DROP: {
- handleNodegroupDropStatement(metadataProvider, stmt);
- break;
- }
-
- case CREATE_FUNCTION: {
- handleCreateFunctionStatement(metadataProvider, stmt);
- break;
- }
-
- case FUNCTION_DROP: {
- handleFunctionDropStatement(metadataProvider, stmt);
- break;
- }
-
- case LOAD_FROM_FILE: {
- handleLoadFromFileStatement(metadataProvider, stmt, hcc);
- break;
- }
- case WRITE_FROM_QUERY_RESULT: {
- handleWriteFromQueryResultStatement(metadataProvider, stmt, hcc);
- break;
- }
- case INSERT: {
- handleInsertStatement(metadataProvider, stmt, hcc);
- break;
- }
- case DELETE: {
- handleDeleteStatement(metadataProvider, stmt, hcc);
- break;
- }
-
- case BEGIN_FEED: {
- handleBeginFeedStatement(metadataProvider, stmt, hcc);
- break;
- }
-
- case CONTROL_FEED: {
- handleControlFeedStatement(metadataProvider, stmt, hcc);
- break;
- }
-
- case QUERY: {
- metadataProvider.setResultSetId(new ResultSetId(resultSetIdCounter++));
- executionResult.add(handleQuery(metadataProvider, (Query) stmt, hcc, hdc, asyncResults));
- break;
- }
-
- case WRITE: {
- Pair<IAWriterFactory, FileSplit> result = handleWriteStatement(metadataProvider, stmt);
- if (result.first != null) {
- writerFactory = result.first;
- }
- outputFile = result.second;
- break;
- }
-
+ switch (stmt.getKind()) {
+ case SET: {
+ handleSetStatement(metadataProvider, stmt, config);
+ break;
}
- } catch (Exception e) {
- throw new AlgebricksException(e);
+ case DATAVERSE_DECL: {
+ activeDefaultDataverse = handleUseDataverseStatement(metadataProvider, stmt);
+ break;
+ }
+ case CREATE_DATAVERSE: {
+ handleCreateDataverseStatement(metadataProvider, stmt);
+ break;
+ }
+ case DATASET_DECL: {
+ handleCreateDatasetStatement(metadataProvider, stmt, hcc);
+ break;
+ }
+ case CREATE_INDEX: {
+ handleCreateIndexStatement(metadataProvider, stmt, hcc);
+ break;
+ }
+ case TYPE_DECL: {
+ handleCreateTypeStatement(metadataProvider, stmt);
+ break;
+ }
+ case NODEGROUP_DECL: {
+ handleCreateNodeGroupStatement(metadataProvider, stmt);
+ break;
+ }
+ case DATAVERSE_DROP: {
+ handleDataverseDropStatement(metadataProvider, stmt, hcc);
+ break;
+ }
+ case DATASET_DROP: {
+ handleDatasetDropStatement(metadataProvider, stmt, hcc);
+ break;
+ }
+ case INDEX_DROP: {
+ handleIndexDropStatement(metadataProvider, stmt, hcc);
+ break;
+ }
+ case TYPE_DROP: {
+ handleTypeDropStatement(metadataProvider, stmt);
+ break;
+ }
+ case NODEGROUP_DROP: {
+ handleNodegroupDropStatement(metadataProvider, stmt);
+ break;
+ }
+
+ case CREATE_FUNCTION: {
+ handleCreateFunctionStatement(metadataProvider, stmt);
+ break;
+ }
+
+ case FUNCTION_DROP: {
+ handleFunctionDropStatement(metadataProvider, stmt);
+ break;
+ }
+
+ case LOAD_FROM_FILE: {
+ handleLoadFromFileStatement(metadataProvider, stmt, hcc);
+ break;
+ }
+ case WRITE_FROM_QUERY_RESULT: {
+ handleWriteFromQueryResultStatement(metadataProvider, stmt, hcc);
+ break;
+ }
+ case INSERT: {
+ handleInsertStatement(metadataProvider, stmt, hcc);
+ break;
+ }
+ case DELETE: {
+ handleDeleteStatement(metadataProvider, stmt, hcc);
+ break;
+ }
+
+ case BEGIN_FEED: {
+ handleBeginFeedStatement(metadataProvider, stmt, hcc);
+ break;
+ }
+
+ case CONTROL_FEED: {
+ handleControlFeedStatement(metadataProvider, stmt, hcc);
+ break;
+ }
+
+ case QUERY: {
+ metadataProvider.setResultSetId(new ResultSetId(resultSetIdCounter++));
+ executionResult.add(handleQuery(metadataProvider, (Query) stmt, hcc, hdc, asyncResults));
+ break;
+ }
+
+ case WRITE: {
+ Pair<IAWriterFactory, FileSplit> result = handleWriteStatement(metadataProvider, stmt);
+ if (result.first != null) {
+ writerFactory = result.first;
+ }
+ outputFile = result.second;
+ break;
+ }
}
}
return executionResult;
@@ -364,7 +359,7 @@
MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
} catch (Exception e) {
abort(e, e, mdTxnCtx);
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseWriteLatch();
}
@@ -528,7 +523,7 @@
}
}
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseWriteLatch();
}
@@ -664,7 +659,7 @@
+ "." + datasetName + "." + indexName + ") couldn't be removed from the metadata", e);
}
}
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseWriteLatch();
}
@@ -703,7 +698,7 @@
MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
} catch (Exception e) {
abort(e, e, mdTxnCtx);
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseWriteLatch();
}
@@ -817,7 +812,7 @@
}
}
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseWriteLatch();
}
@@ -922,7 +917,7 @@
}
}
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseWriteLatch();
}
@@ -1027,7 +1022,7 @@
}
}
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseWriteLatch();
@@ -1054,7 +1049,7 @@
MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
} catch (Exception e) {
abort(e, e, mdTxnCtx);
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseWriteLatch();
}
@@ -1080,7 +1075,7 @@
MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
} catch (Exception e) {
abort(e, e, mdTxnCtx);
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseWriteLatch();
}
@@ -1106,7 +1101,7 @@
MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
} catch (Exception e) {
abort(e, e, mdTxnCtx);
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseWriteLatch();
}
@@ -1130,7 +1125,7 @@
MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
} catch (Exception e) {
abort(e, e, mdTxnCtx);
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseWriteLatch();
}
@@ -1178,7 +1173,7 @@
abort(e, e, mdTxnCtx);
}
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseReadLatch();
}
@@ -1208,7 +1203,7 @@
if (bActiveTxn) {
abort(e, e, mdTxnCtx);
}
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseReadLatch();
}
@@ -1241,7 +1236,7 @@
if (bActiveTxn) {
abort(e, e, mdTxnCtx);
}
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseReadLatch();
}
@@ -1275,7 +1270,7 @@
if (bActiveTxn) {
abort(e, e, mdTxnCtx);
}
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseReadLatch();
}
@@ -1341,7 +1336,7 @@
if (bActiveTxn) {
abort(e, e, mdTxnCtx);
}
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseReadLatch();
}
@@ -1370,7 +1365,7 @@
if (bActiveTxn) {
abort(e, e, mdTxnCtx);
}
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseReadLatch();
}
@@ -1401,29 +1396,38 @@
handle.put(jobId.getId());
handle.put(metadataProvider.getResultSetId().getId());
response.put("handle", handle);
+ out.print(response);
+ out.flush();
} else {
+ if (pdf == DisplayFormat.HTML) {
+ out.println("<h4>Results:</h4>");
+ out.println("<pre>");
+ }
+
ByteBuffer buffer = ByteBuffer.allocate(ResultReader.FRAME_SIZE);
ResultReader resultReader = new ResultReader(hcc, hdc);
resultReader.open(jobId, metadataProvider.getResultSetId());
buffer.clear();
- JSONArray results = new JSONArray();
+
while (resultReader.read(buffer) > 0) {
- results.put(ResultUtils.getJSONFromBuffer(buffer, resultReader.getFrameTupleAccessor()));
+ response.put("results",
+ ResultUtils.getJSONFromBuffer(buffer, resultReader.getFrameTupleAccessor()));
buffer.clear();
+ switch (pdf) {
+ case HTML:
+ ResultUtils.prettyPrintHTML(out, response);
+ break;
+ case TEXT:
+ case JSON:
+ out.print(response);
+ break;
+ }
+ out.flush();
}
- response.put("results", results);
- }
- switch (pdf) {
- case HTML:
- out.println("<h4>Results:</h4>");
- out.println("<pre>");
- ResultUtils.prettyPrintHTML(out, response);
+ if (pdf == DisplayFormat.HTML) {
out.println("</pre>");
- break;
- case TEXT:
- case JSON:
- out.print(response);
- break;
+ }
+
}
hcc.waitForCompletion(jobId);
}
@@ -1434,7 +1438,7 @@
if (bActiveTxn) {
abort(e, e, mdTxnCtx);
}
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseReadLatch();
}
@@ -1464,7 +1468,7 @@
MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
} catch (Exception e) {
abort(e, e, mdTxnCtx);
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseWriteLatch();
}
@@ -1503,8 +1507,7 @@
return format;
}
- private String getActiveDataverseName(String dataverse)
- throws AlgebricksException {
+ private String getActiveDataverseName(String dataverse) throws AlgebricksException {
if (dataverse != null) {
return dataverse;
}
@@ -1513,13 +1516,11 @@
}
throw new AlgebricksException("dataverse not specified");
}
-
- private String getActiveDataverseName(Identifier dataverse)
- throws AlgebricksException {
- return getActiveDataverseName(
- dataverse != null ? dataverse.getValue() : null);
+
+ private String getActiveDataverseName(Identifier dataverse) throws AlgebricksException {
+ return getActiveDataverseName(dataverse != null ? dataverse.getValue() : null);
}
-
+
private void acquireWriteLatch() {
MetadataManager.INSTANCE.acquireWriteLatch();
}
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 02cf6a4..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
@@ -14,14 +14,22 @@
*/
package edu.uci.ics.asterix.result;
+import java.io.BufferedReader;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.PrintWriter;
+import java.io.StringWriter;
import java.nio.ByteBuffer;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import com.sun.el.parser.ParseException;
+
+import edu.uci.ics.asterix.api.http.servlet.APIServlet;
+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;
import edu.uci.ics.hyracks.dataflow.common.comm.util.ByteBufferInputStream;
@@ -51,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.
}
@@ -65,30 +78,116 @@
}
public static void prettyPrintHTML(PrintWriter out, JSONObject jsonResultObj) {
- JSONArray resultsWrapper;
- JSONArray resultsArray;
try {
- resultsWrapper = jsonResultObj.getJSONArray("results");
- for (int i = 0; i < resultsWrapper.length(); i++) {
- resultsArray = resultsWrapper.getJSONArray(i);
- for (int j = 0; j < resultsArray.length(); j++) {
- out.print(resultsArray.getString(j));
- }
+ JSONArray resultsArray = jsonResultObj.getJSONArray("results");
+ for (int i = 0; i < resultsArray.length(); i++) {
+ out.print(resultsArray.getString(i));
}
} catch (JSONException e) {
// TODO(madhusudancs): Figure out what to do when JSONException occurs while building the results.
}
}
+ public static void webUIErrorHandler(PrintWriter out, Exception e) {
+ String errorTemplate = "%s\n%s\n%s";
+ try {
+ String resourcePath = "/webui/errortemplate.html";
+ InputStream is = APIServlet.class.getResourceAsStream(resourcePath);
+ InputStreamReader isr = new InputStreamReader(is);
+ StringBuilder sb = new StringBuilder();
+ BufferedReader br = new BufferedReader(isr);
+ String line = br.readLine();
+
+ while (line != null) {
+ sb.append(line);
+ line = br.readLine();
+ }
+ errorTemplate = sb.toString();
+ } catch (IOException ioe) {
+ // If there is an IOException reading the error template html file, default value of error template is used.
+ }
+
+ String errorOutput = String.format(errorTemplate, extractErrorMessage(e), extractErrorSummary(e),
+ extractFullStackTrace(e));
+ out.println(errorOutput);
+ }
+
+ public static void apiErrorHandler(PrintWriter out, Exception e) {
+ int errorCode = 99;
+ if (e instanceof ParseException) {
+ errorCode = 2;
+ } else if (e instanceof AlgebricksException) {
+ errorCode = 3;
+ } else if (e instanceof HyracksDataException) {
+ errorCode = 4;
+ }
+
+ JSONObject errorResp = ResultUtils.getErrorResponse(errorCode, extractErrorMessage(e), extractErrorSummary(e),
+ extractFullStackTrace(e));
+ out.write(errorResp.toString());
+ }
+
+ public static String buildParseExceptionMessage(Throwable e, String query) {
+ StringBuilder errorMessage = new StringBuilder();
+ String message = e.getMessage();
+ message = message.replace("<", "<");
+ message = message.replace(">", ">");
+ errorMessage.append("SyntaxError:" + message + "\n");
+ int pos = message.indexOf("line");
+ if (pos > 0) {
+ int columnPos = message.indexOf(",", pos + 1 + "line".length());
+ int lineNo = Integer.parseInt(message.substring(pos + "line".length() + 1, columnPos));
+ String[] lines = query.split("\n");
+ if (lineNo >= lines.length) {
+ errorMessage.append("===> <BLANK LINE> \n");
+ } else {
+ String line = lines[lineNo - 1];
+ errorMessage.append("==> " + line);
+ }
+ }
+ return errorMessage.toString();
+ }
+
+ private static Throwable getRootCause(Throwable cause) {
+ Throwable nextCause = cause.getCause();
+ while (nextCause != null) {
+ cause = nextCause;
+ nextCause = cause.getCause();
+ }
+ return cause;
+ }
+
/**
- * extract meaningful part of a stack trace:
+ * Extract the message in the root cause of the stack trace:
+ *
+ * @param e
+ * @return error message string.
+ */
+ private static String extractErrorMessage(Throwable e) {
+ Throwable cause = getRootCause(e);
+
+ String exceptionClassName = "";
+ String[] messageSplits = cause.toString().split(":");
+ if (messageSplits.length > 1) {
+ String fullyQualifiedExceptionClassName = messageSplits[0];
+ System.out.println(fullyQualifiedExceptionClassName);
+ String[] hierarchySplits = fullyQualifiedExceptionClassName.split("\\.");
+ if (hierarchySplits.length > 0) {
+ exceptionClassName = hierarchySplits[hierarchySplits.length - 1];
+ }
+ }
+ return cause.getLocalizedMessage() + " [" + exceptionClassName + "]";
+ }
+
+ /**
+ * Extract the 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) {
+ private static String extractErrorSummary(Throwable e) {
StringBuilder errorMessageBuilder = new StringBuilder();
Throwable cause = e;
errorMessageBuilder.append(cause.getLocalizedMessage());
@@ -99,4 +198,17 @@
}
return errorMessageBuilder.toString();
}
+
+ /**
+ * Extract the full stack trace:
+ *
+ * @param e
+ * @return the string containing the full stack trace of the error.
+ */
+ private static String extractFullStackTrace(Throwable e) {
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter printWriter = new PrintWriter(stringWriter);
+ e.printStackTrace(printWriter);
+ return stringWriter.toString();
+ }
}
diff --git a/asterix-app/src/main/resources/webui/errortemplate.html b/asterix-app/src/main/resources/webui/errortemplate.html
new file mode 100644
index 0000000..8c39e03
--- /dev/null
+++ b/asterix-app/src/main/resources/webui/errortemplate.html
@@ -0,0 +1,38 @@
+<div class="accordion" id="errorblock">
+ <div class="accordion-group">
+ <div class="accordion-heading">
+ <a class="accordion-toggle" data-toggle="collapse" data-parent="#errorblock" href="#levelOne">
+ Message
+ </a>
+ </div>
+ <div id="levelOne" class="accordion-body collapse in">
+ <div class="accordion-inner">
+ <pre class="error">%s</pre>
+ </div>
+ </div>
+ </div>
+ <div class="accordion-group">
+ <div class="accordion-heading">
+ <a class="accordion-toggle" data-toggle="collapse" data-parent="#errorblock" href="#levelTwo">
+ Summary
+ </a>
+ </div>
+ <div id="levelTwo" class="accordion-body collapse">
+ <div class="accordion-inner">
+ <pre class="error">%s</pre>
+ </div>
+ </div>
+ </div>
+ <div class="accordion-group">
+ <div class="accordion-heading">
+ <a class="accordion-toggle" data-toggle="collapse" data-parent="#errorblock" href="#levelThree">
+ Full Stack Trace
+ </a>
+ </div>
+ <div id="levelThree" class="accordion-body collapse">
+ <div class="accordion-inner">
+ <pre class="error">%s</pre>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/asterix-app/src/main/resources/webui/querytemplate.html b/asterix-app/src/main/resources/webui/querytemplate.html
index 9021e0b..40ce161 100644
--- a/asterix-app/src/main/resources/webui/querytemplate.html
+++ b/asterix-app/src/main/resources/webui/querytemplate.html
@@ -54,11 +54,16 @@
var resSet = 0;
var resPattern = /<h4>Results:<\/h4>/g;
var durPattern = /<PRE>Duration/g;
+ var errorPattern = /<div class="accordion" id="errorblock">/g;
var resultCount = data.match(resPattern);
- if (!resPattern.test(data)) {
+ if (!resPattern.test(data) && errorPattern.test(data)) {
+ $('#output-heading').html('Error');
+ $('#output-heading').addClass('error');
$('#output-message').html(data);
- } else {
+ } else {
+ $('#output-heading').html('Output');
+ $('#output-heading').removeClass('error');
if (resultCount.length <= 1) {
$('#output-message').html(data);
} else {
@@ -66,7 +71,7 @@
var results = splitData[0].split('<h4>');
var components = results.slice(1, results.length);
var sections = components.length / resultCount.length;
-
+
for (resSet = 0; resSet < resultCount.length; resSet++) {
$('#output-message').append('<h4>' + components[(resSet+1)*sections - 1]);
@@ -80,12 +85,12 @@
.css("margin-bottom", "1em")
.html('Result Plan #' + resNum + '<i id="ibtn' + resSet + '" class="icon-plus extarget"></i>')
.appendTo('#output-message');
-
+
$('<div/>')
.attr("id", "collapse" + resSet)
.attr("class", "collapse in")
.appendTo('#output-message');
-
+
for (var c = 0; c < sections - 1; c++) {
var pos = resSet*sections + c;
$('#collapse' + resSet).append('<h4>' + components[pos]);
@@ -97,7 +102,7 @@
});
*/
- $('#output-message').append("<hr/>");
+ $('#output-message').append("<hr/>");
}
}
@@ -135,7 +140,7 @@
<!-- Temporary logo placeholder -->
<a class="brand" href="#"><img src="/webui/static/img/finalasterixlogo.png"></a>
-
+
<div class="nav-collapse collapse">
<ul class="nav">
<li><a href="http://code.google.com/p/asterixdb/" target="_blank">
@@ -182,7 +187,7 @@
<div class="span6">
<div class="output">
- <label class="heading">Output</label>
+ <label id="output-heading" class="heading">Output</label>
<div id="output-message" class="message">
</div>
</div>
diff --git a/asterix-app/src/main/resources/webui/static/css/style.css b/asterix-app/src/main/resources/webui/static/css/style.css
index 906181b..a3e411c 100644
--- a/asterix-app/src/main/resources/webui/static/css/style.css
+++ b/asterix-app/src/main/resources/webui/static/css/style.css
@@ -87,6 +87,10 @@
color : #17265a;
}
+div.output label.heading.error {
+ color: #E03809;
+}
+
div.output h4 {
color : #17265a;
}
@@ -95,6 +99,14 @@
color : #17265a;
}
+.accordion-inner {
+ padding : 0 0 0 0;
+}
+
+#errorblock .accordion-group .accordion-heading a.accordion-toggle {
+ color: #E03809;
+}
+
div.output .message {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
@@ -105,22 +117,7 @@
}
div.output .message pre.error {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- -ms-box-sizing: border-box;
- box-sizing: border-box;
- border-color: rgba(82, 168, 236, 0.8);
- outline: 0;
- outline: thin dotted 9;
-
- -webkit-box-shadow: inset 0 1px 1px rgba(250, 0, 0, 0.075), 0 0 8px rgba(255, 0, 0, 0.8);
- -moz-box-shadow: inset 0 1px 1px rgba(250, 0, 0, 0.075), 0 0 8px rgba(255, 0, 0, 1.0);
- box-shadow: inset 0 1px 1px rgba(250, 0, 0, 0.075), 0 0 8px rgba(255, 0, 0, 1.0);
- color: #000;
- resize: none;
- border: 1px solid #eee;
- margin-top: 7px;
- padding: 20px 20px 20px 20px;
+ border: 0;
}
.footer {
diff --git a/asterix-maven-plugins/lexer-generator-maven-plugin/pom.xml b/asterix-maven-plugins/lexer-generator-maven-plugin/pom.xml
index 6b444e8..6be403e 100644
--- a/asterix-maven-plugins/lexer-generator-maven-plugin/pom.xml
+++ b/asterix-maven-plugins/lexer-generator-maven-plugin/pom.xml
@@ -18,8 +18,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
- <source>1.6</source>
- <target>1.6</target>
+ <source>1.7</source>
+ <target>1.7</target>
<fork>true</fork>
</configuration>
</plugin>