Merge master to madhusudancs/error-reporting.
One change missing, we need to include extractErrorMessage from Yingyi which is disabled
during the merge.
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 d378429..2f4cd2a 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
@@ -83,29 +83,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);
}
}
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..d1b2d5f 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,7 +17,6 @@
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;
@@ -32,8 +31,8 @@
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;
import edu.uci.ics.asterix.result.ResultReader;
import edu.uci.ics.asterix.result.ResultUtils;
@@ -95,28 +94,12 @@
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) {
+ 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());
+ ResultUtils.apiErrorHandler(out, e);
}
}
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 911f6fd..5f12fe2 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,28 +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("<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("<pre>");
- ResultUtils.prettyPrintHTML(out, response);
+
+ if (pdf == DisplayFormat.HTML) {
out.println("</pre>");
- break;
- case TEXT:
- case JSON:
- out.print(response);
- break;
+ }
+
}
hcc.waitForCompletion(jobId);
}
@@ -1433,7 +1438,7 @@
if (bActiveTxn) {
abort(e, e, mdTxnCtx);
}
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseReadLatch();
}
@@ -1463,7 +1468,7 @@
MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
} catch (Exception e) {
abort(e, e, mdTxnCtx);
- throw new AlgebricksException(e);
+ throw e;
} finally {
releaseWriteLatch();
}
@@ -1502,8 +1507,7 @@
return format;
}
- private String getActiveDataverseName(String dataverse)
- throws AlgebricksException {
+ private String getActiveDataverseName(String dataverse) throws AlgebricksException {
if (dataverse != null) {
return dataverse;
}
@@ -1512,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();
}
@@ -1543,4 +1545,4 @@
throw new IllegalStateException(rootE);
}
}
-}
\ No newline at end of file
+}
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..8354160 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
@@ -17,11 +17,16 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
+import java.util.logging.Level;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import com.sun.el.parser.ParseException;
+
+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;
import edu.uci.ics.hyracks.dataflow.common.comm.util.ByteBufferInputStream;
@@ -80,6 +85,73 @@
}
}
+ public static void webUIErrorHandler(PrintWriter out, Exception e) {
+ String errPrefix = "";
+ if (e instanceof AlgebricksException) {
+ errPrefix = "Compilation error: ";
+ } else if (e instanceof HyracksDataException) {
+ errPrefix = "Runtime error: ";
+ }
+
+ Throwable cause = getRootCause(e);
+
+ GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, e.getMessage(), e);
+ out.println("<pre class=\"error\">");
+ out.println(errPrefix + cause.getMessage());
+ out.println("</pre>");
+ }
+
+ 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());
+ out.write(errorResp.toString());
+ }
+
+ public static String buildParseExceptionMessage(Throwable e, String query) {
+ GlobalConfig.ASTERIX_LOGGER.log(Level.INFO, e.toString(), e);
+ 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:
* a. the causes in the stack trace hierarchy