ASTERIXDB-1361: Meaningful error when missing output-record-type

Change-Id: Id5ca7d634b2be5164af82ad128ff577c0bdbd457
Reviewed-on: https://asterix-gerrit.ics.uci.edu/741
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <tillw@apache.org>
diff --git a/asterix-app/src/main/java/org/apache/asterix/result/ResultUtils.java b/asterix-app/src/main/java/org/apache/asterix/result/ResultUtils.java
index 2fe7f28..d7ddce5 100644
--- a/asterix-app/src/main/java/org/apache/asterix/result/ResultUtils.java
+++ b/asterix-app/src/main/java/org/apache/asterix/result/ResultUtils.java
@@ -34,6 +34,7 @@
 import org.apache.asterix.api.common.SessionConfig.OutputFormat;
 import org.apache.asterix.api.http.servlet.APIServlet;
 import org.apache.asterix.api.http.servlet.JSONUtil;
+import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.http.ParseException;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -73,7 +74,12 @@
         return s;
     }
 
-    public static void displayCSVHeader(ARecordType recordType, SessionConfig conf) {
+    public static void displayCSVHeader(ARecordType recordType, SessionConfig conf)
+            throws AsterixException {
+        if (recordType == null) {
+            throw new AsterixException(
+               "Cannot output CSV with header without specifying output-record-type");
+        }
         // If HTML-ifying, we have to output this here before the header -
         // pretty ugly
         if (conf.is(SessionConfig.FORMAT_HTML)) {
@@ -251,7 +257,7 @@
         String message = e.getMessage();
         message = message.replace("<", "&lt");
         message = message.replace(">", "&gt");
-        errorMessage.append("SyntaxError: " + message + "\n");
+        errorMessage.append("Error: " + message + "\n");
         int pos = message.indexOf("line");
         if (pos > 0) {
             Pattern p = Pattern.compile("\\d+");
diff --git a/asterix-app/src/test/resources/metadata/testsuite.xml b/asterix-app/src/test/resources/metadata/testsuite.xml
index cb838cc..7a85d57 100644
--- a/asterix-app/src/test/resources/metadata/testsuite.xml
+++ b/asterix-app/src/test/resources/metadata/testsuite.xml
@@ -328,61 +328,61 @@
     <test-case FilePath="exception">
       <compilation-unit name="issue_239_drop_system_dataset_1">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: Invalid operation - Cannot drop a dataset belonging to the dataverse:Metadata</expected-error>
+        <expected-error>Error: Invalid operation - Cannot drop a dataset belonging to the dataverse:Metadata</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
       <compilation-unit name="issue_239_drop_system_dataset_2">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: Invalid operation - Cannot drop a dataset belonging to the dataverse:Metadata</expected-error>
+        <expected-error>Error: Invalid operation - Cannot drop a dataset belonging to the dataverse:Metadata</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
       <compilation-unit name="issue_239_drop_system_dataset_3">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: Invalid operation - Cannot drop a dataset belonging to the dataverse:Metadata</expected-error>
+        <expected-error>Error: Invalid operation - Cannot drop a dataset belonging to the dataverse:Metadata</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
       <compilation-unit name="issue_239_drop_system_dataset_4">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: Invalid operation - Cannot drop a dataset belonging to the dataverse:Metadata</expected-error>
+        <expected-error>Error: Invalid operation - Cannot drop a dataset belonging to the dataverse:Metadata</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
       <compilation-unit name="issue_239_drop_system_dataset_5">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: Invalid operation - Cannot drop a dataset belonging to the dataverse:Metadata</expected-error>
+        <expected-error>Error: Invalid operation - Cannot drop a dataset belonging to the dataverse:Metadata</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
       <compilation-unit name="issue_239_drop_system_dataset_6">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: Invalid operation - Cannot drop a dataset belonging to the dataverse:Metadata</expected-error>
+        <expected-error>Error: Invalid operation - Cannot drop a dataset belonging to the dataverse:Metadata</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
       <compilation-unit name="issue_239_drop_system_dataset_7">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: Invalid operation - Cannot drop a dataset belonging to the dataverse:Metadata</expected-error>
+        <expected-error>Error: Invalid operation - Cannot drop a dataset belonging to the dataverse:Metadata</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
       <compilation-unit name="issue_239_drop_system_dataset_8">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: Invalid operation - Cannot drop a dataset belonging to the dataverse:Metadata</expected-error>
+        <expected-error>Error: Invalid operation - Cannot drop a dataset belonging to the dataverse:Metadata</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
       <compilation-unit name="issue_251_dataset_hint_error_1">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: Invalid operation - Dataset: Book error in processing hint: TUPLE_SIZE Unknown hint</expected-error>
+        <expected-error>Error: Invalid operation - Dataset: Book error in processing hint: TUPLE_SIZE Unknown hint</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
       <compilation-unit name="issue_251_dataset_hint_error_2">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: Invalid operation - Dataset: Book error in processing hint: SIZE Unknown hint</expected-error>
+        <expected-error>Error: Invalid operation - Dataset: Book error in processing hint: SIZE Unknown hint</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
@@ -407,7 +407,7 @@
     <test-case FilePath="exception">
       <compilation-unit name="issue_255_create_dataset_error_2">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: The partitioning key "[open-type]" cannot be of type RECORD.</expected-error>
+        <expected-error>Error: The partitioning key "[open-type]" cannot be of type RECORD.</expected-error>
       </compilation-unit>
     </test-case>
     <!-- Feed datasets are not supported anymore
@@ -427,43 +427,43 @@
     <test-case FilePath="exception">
       <compilation-unit name="issue_266_create_dataset_error_2">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: The partitioning key "[id]" cannot be nullable</expected-error>
+        <expected-error>Error: The partitioning key "[id]" cannot be nullable</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
       <compilation-unit name="issue_384_create_index_error_1">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: The field "[loc]" which is of type POINT cannot be indexed using the BTree index.</expected-error>
+        <expected-error>Error: The field "[loc]" which is of type POINT cannot be indexed using the BTree index.</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
       <compilation-unit name="issue_384_create_index_error_2">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: The field "[age]" which is of type INT32 cannot be indexed using the RTree index.</expected-error>
+        <expected-error>Error: The field "[age]" which is of type INT32 cannot be indexed using the RTree index.</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
       <compilation-unit name="issue_384_create_index_error_3">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: The field "[loc]" which is of type POINT cannot be indexed using the Length Partitioned Keyword index.</expected-error>
+        <expected-error>Error: The field "[loc]" which is of type POINT cannot be indexed using the Length Partitioned Keyword index.</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
       <compilation-unit name="issue_384_create_index_error_4">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: The field "[loc]" which is of type POINT cannot be indexed using the Length Partitioned Keyword index.</expected-error>
+        <expected-error>Error: The field "[loc]" which is of type POINT cannot be indexed using the Length Partitioned Keyword index.</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
       <compilation-unit name="issue_384_create_index_error_5">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: The field "[loc]" which is of type POINT cannot be indexed using the Length Partitioned N-Gram index.</expected-error>
+        <expected-error>Error: The field "[loc]" which is of type POINT cannot be indexed using the Length Partitioned N-Gram index.</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
       <compilation-unit name="issue_384_create_index_error_6">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>SyntaxError: The field "[loc]" which is of type POINT cannot be indexed using the Length Partitioned N-Gram index.</expected-error>
+        <expected-error>Error: The field "[loc]" which is of type POINT cannot be indexed using the Length Partitioned N-Gram index.</expected-error>
       </compilation-unit>
     </test-case>
   </test-group>
diff --git a/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index fbc821a..f159135 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -5889,7 +5889,7 @@
         <test-case FilePath="cross-dataverse">
             <compilation-unit name="cross-dv13">
                 <output-dir compare="Text">cross-dv13</output-dir>
-                <expected-error>SyntaxError: ERROR:Recursive invocation testdv2.fun03@0</expected-error>
+                <expected-error>Error: ERROR:Recursive invocation testdv2.fun03@0</expected-error>
             </compilation-unit>
         </test-case>
         <test-case FilePath="cross-dataverse">
@@ -5905,7 +5905,7 @@
         <test-case FilePath="cross-dataverse">
             <compilation-unit name="cross-dv16">
                 <output-dir compare="Text">cross-dv16</output-dir>
-                <expected-error>SyntaxError: ERROR:Recursive invocation testdv1.fun04@0</expected-error>
+                <expected-error>Error: ERROR:Recursive invocation testdv1.fun04@0</expected-error>
             </compilation-unit>
         </test-case>
         <!--NotImplementedException: No binary comparator factory implemented for type RECORD.
@@ -5944,19 +5944,19 @@
         <test-case FilePath="cross-dataverse">
             <compilation-unit name="drop-type-used-elsewhere">
                 <output-dir compare="Text">drop-type-used-elsewhere</output-dir>
-                <expected-error>SyntaxError: Cannot drop type a.a being used by dataset b.b1</expected-error>
+                <expected-error>Error: Cannot drop type a.a being used by dataset b.b1</expected-error>
             </compilation-unit>
         </test-case>
         <test-case FilePath="cross-dataverse">
             <compilation-unit name="drop-type-used-here-dataset">
                 <output-dir compare="Text">drop-type-used-here-dataset</output-dir>
-                <expected-error>SyntaxError: Cannot drop type c.a being used by dataset c.a1</expected-error>
+                <expected-error>Error: Cannot drop type c.a being used by dataset c.a1</expected-error>
             </compilation-unit>
         </test-case>
         <test-case FilePath="cross-dataverse">
             <compilation-unit name="drop-type-used-here-type">
                 <output-dir compare="Text">drop-type-used-here-type</output-dir>
-                <expected-error>SyntaxError: Cannot drop type c.a being used by type c.b</expected-error>
+                <expected-error>Error: Cannot drop type c.a being used by type c.b</expected-error>
             </compilation-unit>
         </test-case>
         <test-case FilePath="cross-dataverse">
@@ -5989,7 +5989,7 @@
         <test-case FilePath="user-defined-functions">
             <compilation-unit name="query-issue455">
                 <output-dir compare="Text">query-issue455</output-dir>
-                <expected-error>SyntaxError:  function test.printName@0 is undefined</expected-error>
+                <expected-error>Error:  function test.printName@0 is undefined</expected-error>
             </compilation-unit>
         </test-case>
         <test-case FilePath="user-defined-functions">
@@ -6133,7 +6133,7 @@
         <test-case FilePath="user-defined-functions">
             <compilation-unit name="udf26"><!-- Error not propagated properly -->
                 <output-dir compare="Text">udf26</output-dir>
-                <expected-error>SyntaxError:  function test.needs_f1@1 depends upon function test.f1@0 which is undefined</expected-error>
+                <expected-error>Error:  function test.needs_f1@1 depends upon function test.f1@0 which is undefined</expected-error>
             </compilation-unit>
         </test-case>
         <test-case FilePath="user-defined-functions"><!-- Exception is never thrown!! -->
@@ -6154,7 +6154,7 @@
         <test-case FilePath="user-defined-functions">
             <compilation-unit name="udf30">
                 <output-dir compare="Text">udf30</output-dir>
-                <expected-error>SyntaxError: can't find variable $y</expected-error>
+                <expected-error>Error: can't find variable $y</expected-error>
             </compilation-unit>
         </test-case>
         <test-case FilePath="user-defined-functions">
@@ -6165,7 +6165,7 @@
         <test-case FilePath="user-defined-functions">
             <compilation-unit name="f01">
                 <output-dir compare="Text">f01</output-dir>
-                <expected-error>SyntaxError:  function test.int8@0 is undefined</expected-error>
+                <expected-error>Error:  function test.int8@0 is undefined</expected-error>
             </compilation-unit>
         </test-case>
         <test-case FilePath="user-defined-functions">
diff --git a/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index 128b1eb..8357e3e 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -2729,7 +2729,7 @@
             <test-case FilePath="open-index-enforced/error-checking">
                 <compilation-unit name="enforced-field-type-collision">
                     <output-dir compare="Text">enforced-field-type-collision</output-dir>
-                    <expected-error>SyntaxError: A field "[value]" is already defined with the type "STRING"</expected-error>
+                    <expected-error>Error: A field "[value]" is already defined with the type "STRING"</expected-error>
                 </compilation-unit>
             </test-case>
             <test-case FilePath="open-index-enforced/error-checking">
@@ -5674,7 +5674,7 @@
         <test-case FilePath="cross-dataverse">
             <compilation-unit name="cross-dv13">
                 <output-dir compare="Text">cross-dv13</output-dir>
-                <expected-error>SyntaxError: ERROR:Recursive invocation testdv2.fun03@0</expected-error>
+                <expected-error>Error: ERROR:Recursive invocation testdv2.fun03@0</expected-error>
             </compilation-unit>
         </test-case>
         <test-case FilePath="cross-dataverse">
@@ -5690,7 +5690,7 @@
         <test-case FilePath="cross-dataverse">
             <compilation-unit name="cross-dv16">
                 <output-dir compare="Text">cross-dv16</output-dir>
-                <expected-error>SyntaxError: ERROR:Recursive invocation testdv1.fun04@0</expected-error>
+                <expected-error>Error: ERROR:Recursive invocation testdv1.fun04@0</expected-error>
             </compilation-unit>
         </test-case>
         <!--NotImplementedException: No binary comparator factory implemented for type RECORD.
@@ -5752,7 +5752,7 @@
         <test-case FilePath="user-defined-functions">
             <compilation-unit name="query-issue455">
                 <output-dir compare="Text">query-issue455</output-dir>
-                <expected-error>SyntaxError:  function test.printName@0 is undefined</expected-error>
+                <expected-error>Error:  function test.printName@0 is undefined</expected-error>
             </compilation-unit>
         </test-case>
         <test-case FilePath="user-defined-functions">
@@ -5896,7 +5896,7 @@
         <test-case FilePath="user-defined-functions">
             <compilation-unit name="udf26">
                 <output-dir compare="Text">udf26</output-dir>
-                <expected-error>SyntaxError:  function test.needs_f1@1 depends upon function test.f1@0 which is undefined</expected-error>
+                <expected-error>Error:  function test.needs_f1@1 depends upon function test.f1@0 which is undefined</expected-error>
             </compilation-unit>
         </test-case>
         <test-case FilePath="user-defined-functions">
@@ -5918,13 +5918,13 @@
         <test-case FilePath="user-defined-functions">
             <compilation-unit name="udf30">
                 <output-dir compare="Text">udf30</output-dir>
-                <expected-error>SyntaxError: </expected-error>
+                <expected-error>Error: </expected-error>
             </compilation-unit>
         </test-case>
         <test-case FilePath="user-defined-functions">
             <compilation-unit name="f01">
                 <output-dir compare="Text">f01</output-dir>
-                <expected-error>SyntaxError:  function test.int8@0 is undefined</expected-error>
+                <expected-error>Error:  function test.int8@0 is undefined</expected-error>
             </compilation-unit>
         </test-case>
         <!-- This test case is not valid anymore since we do not required "IMPORT_PRIVATE_FUNCTIONS" flag anymore -->