Explorar o código

Change ObjectParser exception (#31030)

ObjectParser should throw XContentParseExceptions, not IAE. A dedicated parsing
exception can includes the place where the error occurred.

Closes #30605
Christoph Büscher %!s(int64=7) %!d(string=hai) anos
pai
achega
3f87c79500
Modificáronse 18 ficheiros con 87 adicións e 88 borrados
  1. 4 3
      libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ObjectParser.java
  2. 7 13
      libs/x-content/src/test/java/org/elasticsearch/common/xcontent/ObjectParserTests.java
  3. 0 6
      modules/mapper-extras/src/test/java/org/elasticsearch/index/query/FeatureQueryBuilderTests.java
  4. 4 3
      modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/DiscountedCumulativeGainTests.java
  5. 4 3
      modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/MeanReciprocalRankTests.java
  6. 4 3
      modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/PrecisionAtKTests.java
  7. 4 3
      modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RatedDocumentTests.java
  8. 5 3
      server/src/test/java/org/elasticsearch/action/admin/cluster/settings/ClusterUpdateSettingsRequestTests.java
  9. 6 4
      server/src/test/java/org/elasticsearch/action/update/UpdateRequestTests.java
  10. 9 9
      server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightBuilderTests.java
  11. 3 2
      server/src/test/java/org/elasticsearch/search/rescore/QueryRescorerBuilderTests.java
  12. 5 4
      server/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java
  13. 6 7
      server/src/test/java/org/elasticsearch/search/sort/ScriptSortBuilderTests.java
  14. 10 4
      test/framework/src/main/java/org/elasticsearch/test/AbstractQueryTestCase.java
  15. 4 3
      x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/datafeed/DatafeedConfigTests.java
  16. 4 2
      x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/job/config/JobTests.java
  17. 3 4
      x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/process/autodetect/output/AutodetectResultsParserTests.java
  18. 5 12
      x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/common/text/TextTemplateTests.java

+ 4 - 3
libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ObjectParser.java

@@ -155,7 +155,7 @@ public final class ObjectParser<Value, Context> extends AbstractObjectParser<Val
         while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
             if (token == XContentParser.Token.FIELD_NAME) {
                 currentFieldName = parser.currentName();
-                fieldParser = getParser(currentFieldName);
+                fieldParser = getParser(currentFieldName, parser);
             } else {
                 if (currentFieldName == null) {
                     throw new XContentParseException(parser.getTokenLocation(), "[" + name  + "] no field found");
@@ -341,10 +341,11 @@ public final class ObjectParser<Value, Context> extends AbstractObjectParser<Val
         }
     }
 
-    private FieldParser getParser(String fieldName) {
+    private FieldParser getParser(String fieldName, XContentParser xContentParser) {
         FieldParser parser = fieldParserMap.get(fieldName);
         if (parser == null && false == ignoreUnknownFields) {
-            throw new IllegalArgumentException("[" + name  + "] unknown field [" + fieldName + "], parser not found");
+            throw new XContentParseException(xContentParser.getTokenLocation(),
+                    "[" + name + "] unknown field [" + fieldName + "], parser not found");
         }
         return parser;
     }

+ 7 - 13
libs/x-content/src/test/java/org/elasticsearch/common/xcontent/ObjectParserTests.java

@@ -35,7 +35,6 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
-import static org.hamcrest.CoreMatchers.startsWith;
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.hasSize;
 
@@ -186,7 +185,6 @@ public class ObjectParserTests extends ESTestCase {
     }
 
     public void testExceptions() throws IOException {
-        XContentParser parser = createParser(JsonXContent.jsonXContent, "{\"test\" : \"foo\"}");
         class TestStruct {
             public void setTest(int test) {
             }
@@ -195,20 +193,16 @@ public class ObjectParserTests extends ESTestCase {
         TestStruct s = new TestStruct();
         objectParser.declareInt(TestStruct::setTest, new ParseField("test"));
 
-        try {
-            objectParser.parse(parser, s, null);
-            fail("numeric value expected");
-        } catch (XContentParseException ex) {
+        {
+            XContentParser parser = createParser(JsonXContent.jsonXContent, "{\"test\" : \"foo\"}");
+            XContentParseException ex = expectThrows(XContentParseException.class, () -> objectParser.parse(parser, s, null));
             assertThat(ex.getMessage(), containsString("[the_parser] failed to parse field [test]"));
             assertTrue(ex.getCause() instanceof NumberFormatException);
         }
-
-        parser = createParser(JsonXContent.jsonXContent, "{\"not_supported_field\" : \"foo\"}");
-        try {
-            objectParser.parse(parser, s, null);
-            fail("field not supported");
-        } catch (IllegalArgumentException ex) {
-            assertEquals(ex.getMessage(), "[the_parser] unknown field [not_supported_field], parser not found");
+        {
+            XContentParser parser = createParser(JsonXContent.jsonXContent, "{\"not_supported_field\" : \"foo\"}");
+            XContentParseException ex = expectThrows(XContentParseException.class, () -> objectParser.parse(parser, s, null));
+            assertEquals(ex.getMessage(), "[1:2] [the_parser] unknown field [not_supported_field], parser not found");
         }
     }
 

+ 0 - 6
modules/mapper-extras/src/test/java/org/elasticsearch/index/query/FeatureQueryBuilderTests.java

@@ -84,12 +84,6 @@ public class FeatureQueryBuilderTests extends AbstractQueryTestCase<FeatureQuery
         assertThat(query, either(instanceOf(MatchNoDocsQuery.class)).or(instanceOf(expectedClass)));
     }
 
-    @Override
-    @AwaitsFix(bugUrl="https://github.com/elastic/elasticsearch/issues/30605")
-    public void testUnknownField() {
-        super.testUnknownField();
-    }
-
     public void testDefaultScoreFunction() throws IOException {
         assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
         String query = "{\n" +

+ 4 - 3
modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/DiscountedCumulativeGainTests.java

@@ -25,6 +25,7 @@ import org.elasticsearch.common.text.Text;
 import org.elasticsearch.common.xcontent.ToXContent;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentParseException;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.XContentType;
 import org.elasticsearch.common.xcontent.json.JsonXContent;
@@ -41,7 +42,7 @@ import java.util.List;
 import static org.elasticsearch.index.rankeval.EvaluationMetric.filterUnknownDocuments;
 import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode;
 import static org.elasticsearch.test.XContentTestUtils.insertRandomFields;
-import static org.hamcrest.Matchers.startsWith;
+import static org.hamcrest.CoreMatchers.containsString;
 
 public class DiscountedCumulativeGainTests extends ESTestCase {
 
@@ -280,9 +281,9 @@ public class DiscountedCumulativeGainTests extends ESTestCase {
         try (XContentParser parser = createParser(xContentType.xContent(), withRandomFields)) {
             parser.nextToken();
             parser.nextToken();
-            IllegalArgumentException exception = expectThrows(IllegalArgumentException.class,
+            XContentParseException exception = expectThrows(XContentParseException.class,
                     () -> DiscountedCumulativeGain.fromXContent(parser));
-            assertThat(exception.getMessage(), startsWith("[dcg_at] unknown field"));
+            assertThat(exception.getMessage(), containsString("[dcg_at] unknown field"));
         }
     }
 

+ 4 - 3
modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/MeanReciprocalRankTests.java

@@ -25,6 +25,7 @@ import org.elasticsearch.common.text.Text;
 import org.elasticsearch.common.xcontent.ToXContent;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentParseException;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.XContentType;
 import org.elasticsearch.common.xcontent.json.JsonXContent;
@@ -41,7 +42,7 @@ import java.util.List;
 
 import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode;
 import static org.elasticsearch.test.XContentTestUtils.insertRandomFields;
-import static org.hamcrest.Matchers.startsWith;
+import static org.hamcrest.CoreMatchers.containsString;
 
 public class MeanReciprocalRankTests extends ESTestCase {
 
@@ -189,9 +190,9 @@ public class MeanReciprocalRankTests extends ESTestCase {
         try (XContentParser parser = createParser(xContentType.xContent(), withRandomFields)) {
             parser.nextToken();
             parser.nextToken();
-            IllegalArgumentException exception = expectThrows(IllegalArgumentException.class,
+            XContentParseException exception = expectThrows(XContentParseException.class,
                     () -> MeanReciprocalRank.fromXContent(parser));
-            assertThat(exception.getMessage(), startsWith("[reciprocal_rank] unknown field"));
+            assertThat(exception.getMessage(), containsString("[reciprocal_rank] unknown field"));
         }
     }
 

+ 4 - 3
modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/PrecisionAtKTests.java

@@ -25,6 +25,7 @@ import org.elasticsearch.common.text.Text;
 import org.elasticsearch.common.xcontent.ToXContent;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentParseException;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.XContentType;
 import org.elasticsearch.common.xcontent.json.JsonXContent;
@@ -41,7 +42,7 @@ import java.util.List;
 
 import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode;
 import static org.elasticsearch.test.XContentTestUtils.insertRandomFields;
-import static org.hamcrest.Matchers.startsWith;
+import static org.hamcrest.CoreMatchers.containsString;
 
 public class PrecisionAtKTests extends ESTestCase {
 
@@ -203,8 +204,8 @@ public class PrecisionAtKTests extends ESTestCase {
         try (XContentParser parser = createParser(xContentType.xContent(), withRandomFields)) {
             parser.nextToken();
             parser.nextToken();
-            IllegalArgumentException exception = expectThrows(IllegalArgumentException.class, () -> PrecisionAtK.fromXContent(parser));
-            assertThat(exception.getMessage(), startsWith("[precision] unknown field"));
+            XContentParseException exception = expectThrows(XContentParseException.class, () -> PrecisionAtK.fromXContent(parser));
+            assertThat(exception.getMessage(), containsString("[precision] unknown field"));
         }
     }
 

+ 4 - 3
modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RatedDocumentTests.java

@@ -24,6 +24,7 @@ import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
 import org.elasticsearch.common.xcontent.ToXContent;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentParseException;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.XContentType;
 import org.elasticsearch.test.ESTestCase;
@@ -33,7 +34,7 @@ import java.util.Collections;
 
 import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode;
 import static org.elasticsearch.test.XContentTestUtils.insertRandomFields;
-import static org.hamcrest.Matchers.startsWith;
+import static org.hamcrest.CoreMatchers.containsString;
 
 public class RatedDocumentTests extends ESTestCase {
 
@@ -59,8 +60,8 @@ public class RatedDocumentTests extends ESTestCase {
         BytesReference originalBytes = toShuffledXContent(testItem, xContentType, ToXContent.EMPTY_PARAMS, randomBoolean());
         BytesReference withRandomFields = insertRandomFields(xContentType, originalBytes, null, random());
         try (XContentParser parser = createParser(xContentType.xContent(), withRandomFields)) {
-            Exception exception = expectThrows(IllegalArgumentException.class, () -> RatedDocument.fromXContent(parser));
-            assertThat(exception.getMessage(), startsWith("[rated_document] unknown field"));
+            XContentParseException exception = expectThrows(XContentParseException.class, () -> RatedDocument.fromXContent(parser));
+            assertThat(exception.getMessage(), containsString("[rated_document] unknown field"));
         }
     }
 

+ 5 - 3
server/src/test/java/org/elasticsearch/action/admin/cluster/settings/ClusterUpdateSettingsRequestTests.java

@@ -21,6 +21,7 @@ package org.elasticsearch.action.admin.cluster.settings;
 
 import org.elasticsearch.common.bytes.BytesReference;
 import org.elasticsearch.common.xcontent.ToXContent;
+import org.elasticsearch.common.xcontent.XContentParseException;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.XContentType;
 import org.elasticsearch.test.ESTestCase;
@@ -29,7 +30,8 @@ import org.elasticsearch.test.XContentTestUtils;
 import java.io.IOException;
 import java.util.Collections;
 
-import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;;
 
 public class ClusterUpdateSettingsRequestTests extends ESTestCase {
 
@@ -51,10 +53,10 @@ public class ClusterUpdateSettingsRequestTests extends ESTestCase {
             String unsupportedField = "unsupported_field";
             BytesReference mutated = BytesReference.bytes(XContentTestUtils.insertIntoXContent(xContentType.xContent(), originalBytes,
                     Collections.singletonList(""), () -> unsupportedField, () -> randomAlphaOfLengthBetween(3, 10)));
-            IllegalArgumentException iae = expectThrows(IllegalArgumentException.class,
+            XContentParseException iae = expectThrows(XContentParseException.class,
                     () -> ClusterUpdateSettingsRequest.fromXContent(createParser(xContentType.xContent(), mutated)));
             assertThat(iae.getMessage(),
-                    equalTo("[cluster_update_settings_request] unknown field [" + unsupportedField + "], parser not found"));
+                    containsString("[cluster_update_settings_request] unknown field [" + unsupportedField + "], parser not found"));
         } else {
             XContentParser parser = createParser(xContentType.xContent(), originalBytes);
             ClusterUpdateSettingsRequest parsedRequest = ClusterUpdateSettingsRequest.fromXContent(parser);

+ 6 - 4
server/src/test/java/org/elasticsearch/action/update/UpdateRequestTests.java

@@ -33,6 +33,7 @@ import org.elasticsearch.common.xcontent.ToXContent;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.common.xcontent.XContentHelper;
+import org.elasticsearch.common.xcontent.XContentParseException;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.XContentType;
 import org.elasticsearch.common.xcontent.json.JsonXContent;
@@ -70,6 +71,7 @@ public class UpdateRequestTests extends ESTestCase {
 
     private UpdateHelper updateHelper;
 
+    @Override
     @Before
     public void setUp() throws Exception {
         super.setUp();
@@ -283,8 +285,8 @@ public class UpdateRequestTests extends ESTestCase {
                     .field("unknown_field", "test")
                 .endObject());
 
-        IllegalArgumentException ex = expectThrows(IllegalArgumentException.class, () -> request.fromXContent(contentParser));
-        assertEquals("[UpdateRequest] unknown field [unknown_field], parser not found", ex.getMessage());
+        XContentParseException ex = expectThrows(XContentParseException.class, () -> request.fromXContent(contentParser));
+        assertEquals("[1:2] [UpdateRequest] unknown field [unknown_field], parser not found", ex.getMessage());
 
         UpdateRequest request2 = new UpdateRequest("test", "type", "1");
         XContentParser unknownObject = createParser(XContentFactory.jsonBuilder()
@@ -294,8 +296,8 @@ public class UpdateRequestTests extends ESTestCase {
                         .field("count", 1)
                     .endObject()
                 .endObject());
-        ex = expectThrows(IllegalArgumentException.class, () -> request2.fromXContent(unknownObject));
-        assertEquals("[UpdateRequest] unknown field [params], parser not found", ex.getMessage());
+        ex = expectThrows(XContentParseException.class, () -> request2.fromXContent(unknownObject));
+        assertEquals("[1:76] [UpdateRequest] unknown field [params], parser not found", ex.getMessage());
     }
 
     public void testFetchSourceParsing() throws Exception {

+ 9 - 9
server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightBuilderTests.java

@@ -158,10 +158,10 @@ public class HighlightBuilderTests extends ESTestCase {
      */
     public void testUnknownArrayNameExpection() throws IOException {
         {
-            IllegalArgumentException e = expectParseThrows(IllegalArgumentException.class, "{\n" +
+            XContentParseException e = expectParseThrows(XContentParseException.class, "{\n" +
                     "    \"bad_fieldname\" : [ \"field1\" 1 \"field2\" ]\n" +
                     "}\n");
-            assertEquals("[highlight] unknown field [bad_fieldname], parser not found", e.getMessage());
+            assertEquals("[2:5] [highlight] unknown field [bad_fieldname], parser not found", e.getMessage());
         }
 
         {
@@ -174,7 +174,7 @@ public class HighlightBuilderTests extends ESTestCase {
                     "}\n");
             assertThat(e.getMessage(), containsString("[highlight] failed to parse field [fields]"));
             assertThat(e.getCause().getMessage(), containsString("[fields] failed to parse field [body]"));
-            assertEquals("[highlight_field] unknown field [bad_fieldname], parser not found", e.getCause().getCause().getMessage());
+            assertEquals("[4:9] [highlight_field] unknown field [bad_fieldname], parser not found", e.getCause().getCause().getMessage());
         }
     }
 
@@ -188,10 +188,10 @@ public class HighlightBuilderTests extends ESTestCase {
      */
     public void testUnknownFieldnameExpection() throws IOException {
         {
-            IllegalArgumentException e = expectParseThrows(IllegalArgumentException.class, "{\n" +
+            XContentParseException e = expectParseThrows(XContentParseException.class, "{\n" +
                     "    \"bad_fieldname\" : \"value\"\n" +
                     "}\n");
-            assertEquals("[highlight] unknown field [bad_fieldname], parser not found", e.getMessage());
+            assertEquals("[2:5] [highlight] unknown field [bad_fieldname], parser not found", e.getMessage());
         }
 
         {
@@ -204,7 +204,7 @@ public class HighlightBuilderTests extends ESTestCase {
                     "}\n");
             assertThat(e.getMessage(), containsString("[highlight] failed to parse field [fields]"));
             assertThat(e.getCause().getMessage(), containsString("[fields] failed to parse field [body]"));
-            assertEquals("[highlight_field] unknown field [bad_fieldname], parser not found", e.getCause().getCause().getMessage());
+            assertEquals("[4:9] [highlight_field] unknown field [bad_fieldname], parser not found", e.getCause().getCause().getMessage());
         }
     }
 
@@ -213,10 +213,10 @@ public class HighlightBuilderTests extends ESTestCase {
      */
     public void testUnknownObjectFieldnameExpection() throws IOException {
         {
-            IllegalArgumentException e = expectParseThrows(IllegalArgumentException.class, "{\n" +
+            XContentParseException e = expectParseThrows(XContentParseException.class, "{\n" +
                     "    \"bad_fieldname\" :  { \"field\" : \"value\" }\n \n" +
                     "}\n");
-            assertEquals("[highlight] unknown field [bad_fieldname], parser not found", e.getMessage());
+            assertEquals("[2:5] [highlight] unknown field [bad_fieldname], parser not found", e.getMessage());
         }
 
         {
@@ -229,7 +229,7 @@ public class HighlightBuilderTests extends ESTestCase {
                     "}\n");
             assertThat(e.getMessage(), containsString("[highlight] failed to parse field [fields]"));
             assertThat(e.getCause().getMessage(), containsString("[fields] failed to parse field [body]"));
-            assertEquals("[highlight_field] unknown field [bad_fieldname], parser not found", e.getCause().getCause().getMessage());
+            assertEquals("[4:9] [highlight_field] unknown field [bad_fieldname], parser not found", e.getCause().getCause().getMessage());
         }
     }
 

+ 3 - 2
server/src/test/java/org/elasticsearch/search/rescore/QueryRescorerBuilderTests.java

@@ -170,6 +170,7 @@ public class QueryRescorerBuilderTests extends ESTestCase {
 
     class AlwaysRewriteQueryBuilder extends MatchAllQueryBuilder {
 
+        @Override
         protected QueryBuilder doRewrite(QueryRewriteContext queryShardContext) throws IOException {
             return new MatchAllQueryBuilder();
         }
@@ -254,8 +255,8 @@ public class QueryRescorerBuilderTests extends ESTestCase {
                 "}\n";
         {
             XContentParser parser = createParser(rescoreElement);
-            Exception e = expectThrows(IllegalArgumentException.class, () -> RescorerBuilder.parseFromXContent(parser));
-            assertEquals("[query] unknown field [bad_fieldname], parser not found", e.getMessage());
+            XContentParseException e = expectThrows(XContentParseException.class, () -> RescorerBuilder.parseFromXContent(parser));
+            assertEquals("[3:17] [query] unknown field [bad_fieldname], parser not found", e.getMessage());
         }
 
         rescoreElement = "{\n" +

+ 5 - 4
server/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java

@@ -26,6 +26,7 @@ import org.apache.lucene.search.SortedNumericSortField;
 import org.apache.lucene.search.SortedSetSelector;
 import org.apache.lucene.search.SortedSetSortField;
 import org.apache.lucene.search.TermQuery;
+import org.elasticsearch.common.xcontent.XContentParseException;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.json.JsonXContent;
 import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource;
@@ -309,8 +310,8 @@ public class FieldSortBuilderTests extends AbstractSortTestCase<FieldSortBuilder
         parser.nextToken();
         parser.nextToken();
 
-        IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> FieldSortBuilder.fromXContent(parser, ""));
-        assertEquals("[field_sort] unknown field [reverse], parser not found", e.getMessage());
+        XContentParseException e = expectThrows(XContentParseException.class, () -> FieldSortBuilder.fromXContent(parser, ""));
+        assertEquals("[1:18] [field_sort] unknown field [reverse], parser not found", e.getMessage());
     }
 
     @Override
@@ -383,7 +384,7 @@ public class FieldSortBuilderTests extends AbstractSortTestCase<FieldSortBuilder
             }
         };
         sortBuilder.setNestedPath("path").setNestedFilter(rangeQuery);
-        FieldSortBuilder rewritten = (FieldSortBuilder) sortBuilder
+        FieldSortBuilder rewritten = sortBuilder
                 .rewrite(createMockShardContext());
         assertNotSame(rangeQuery, rewritten.getNestedFilter());
     }
@@ -400,7 +401,7 @@ public class FieldSortBuilderTests extends AbstractSortTestCase<FieldSortBuilder
             }
         };
         sortBuilder.setNestedSort(new NestedSortBuilder("path").setFilter(rangeQuery));
-        FieldSortBuilder rewritten = (FieldSortBuilder) sortBuilder
+        FieldSortBuilder rewritten = sortBuilder
                 .rewrite(createMockShardContext());
         assertNotSame(rangeQuery, rewritten.getNestedSort().getFilter());
     }

+ 6 - 7
server/src/test/java/org/elasticsearch/search/sort/ScriptSortBuilderTests.java

@@ -24,7 +24,6 @@ import org.apache.lucene.index.Term;
 import org.apache.lucene.search.MatchAllDocsQuery;
 import org.apache.lucene.search.SortField;
 import org.apache.lucene.search.TermQuery;
-import org.elasticsearch.common.ParsingException;
 import org.elasticsearch.common.xcontent.XContentParseException;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.json.JsonXContent;
@@ -225,8 +224,8 @@ public class ScriptSortBuilderTests extends AbstractSortTestCase<ScriptSortBuild
         parser.nextToken();
         parser.nextToken();
 
-        Exception e = expectThrows(IllegalArgumentException.class, () -> ScriptSortBuilder.fromXContent(parser, null));
-        assertEquals("[_script] unknown field [bad_field], parser not found", e.getMessage());
+        XContentParseException e = expectThrows(XContentParseException.class, () -> ScriptSortBuilder.fromXContent(parser, null));
+        assertEquals("[1:15] [_script] unknown field [bad_field], parser not found", e.getMessage());
     }
 
     public void testParseBadFieldNameExceptionsOnStartObject() throws IOException {
@@ -237,8 +236,8 @@ public class ScriptSortBuilderTests extends AbstractSortTestCase<ScriptSortBuild
         parser.nextToken();
         parser.nextToken();
 
-        Exception e = expectThrows(IllegalArgumentException.class, () -> ScriptSortBuilder.fromXContent(parser, null));
-        assertEquals("[_script] unknown field [bad_field], parser not found", e.getMessage());
+        XContentParseException e = expectThrows(XContentParseException.class, () -> ScriptSortBuilder.fromXContent(parser, null));
+        assertEquals("[1:15] [_script] unknown field [bad_field], parser not found", e.getMessage());
     }
 
     public void testParseUnexpectedToken() throws IOException {
@@ -374,7 +373,7 @@ public class ScriptSortBuilderTests extends AbstractSortTestCase<ScriptSortBuild
             }
         };
         sortBuilder.setNestedPath("path").setNestedFilter(rangeQuery);
-        ScriptSortBuilder rewritten = (ScriptSortBuilder) sortBuilder
+        ScriptSortBuilder rewritten = sortBuilder
                 .rewrite(createMockShardContext());
         assertNotSame(rangeQuery, rewritten.getNestedFilter());
     }
@@ -391,7 +390,7 @@ public class ScriptSortBuilderTests extends AbstractSortTestCase<ScriptSortBuild
             }
         };
         sortBuilder.setNestedSort(new NestedSortBuilder("path").setFilter(rangeQuery));
-        ScriptSortBuilder rewritten = (ScriptSortBuilder) sortBuilder
+        ScriptSortBuilder rewritten = sortBuilder
                 .rewrite(createMockShardContext());
         assertNotSame(rangeQuery, rewritten.getNestedSort().getFilter());
     }

+ 10 - 4
test/framework/src/main/java/org/elasticsearch/test/AbstractQueryTestCase.java

@@ -132,8 +132,9 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
      * To find the right position in the root query, we add a marker as `queryName` which
      * all query builders support. The added bogus field after that should trigger the exception.
      * Queries that allow arbitrary field names at this level need to override this test.
+     * @throws IOException
      */
-    public void testUnknownField() {
+    public void testUnknownField() throws IOException {
         String marker = "#marker#";
         QB testQuery;
         do {
@@ -141,9 +142,14 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
         } while (testQuery.toString().contains(marker));
         testQuery.queryName(marker); // to find root query to add additional bogus field there
         String queryAsString = testQuery.toString().replace("\"" + marker + "\"", "\"" + marker + "\", \"bogusField\" : \"someValue\"");
-        ParsingException e = expectThrows(ParsingException.class, () -> parseQuery(queryAsString));
-        // we'd like to see the offending field name here
-        assertThat(e.getMessage(), containsString("bogusField"));
+        try {
+            parseQuery(queryAsString);
+            fail("expected ParsingException or XContentParsingException");
+        } catch (ParsingException | XContentParseException e) {
+            // we'd like to see the offending field name here
+            assertThat(e.getMessage(), containsString("bogusField"));
+        }
+
     }
 
     /**

+ 4 - 3
x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/datafeed/DatafeedConfigTests.java

@@ -6,15 +6,16 @@
 package org.elasticsearch.xpack.core.ml.datafeed;
 
 import com.carrotsearch.randomizedtesting.generators.CodepointSetGenerator;
+
 import org.elasticsearch.ElasticsearchException;
 import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
 import org.elasticsearch.common.io.stream.Writeable;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.unit.TimeValue;
 import org.elasticsearch.common.xcontent.DeprecationHandler;
-import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
 import org.elasticsearch.common.xcontent.NamedXContentRegistry;
 import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentParseException;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.XContentType;
 import org.elasticsearch.index.query.BoolQueryBuilder;
@@ -155,9 +156,9 @@ public class DatafeedConfigTests extends AbstractSerializingTestCase<DatafeedCon
     public void testFutureConfigParse() throws IOException {
         XContentParser parser = XContentFactory.xContent(XContentType.JSON)
                 .createParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, FUTURE_DATAFEED);
-        IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
+        XContentParseException e = expectThrows(XContentParseException.class,
                 () -> DatafeedConfig.CONFIG_PARSER.apply(parser, null).build());
-        assertEquals("[datafeed_config] unknown field [tomorrows_technology_today], parser not found", e.getMessage());
+        assertEquals("[6:5] [datafeed_config] unknown field [tomorrows_technology_today], parser not found", e.getMessage());
     }
 
     public void testFutureMetadataParse() throws IOException {

+ 4 - 2
x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/job/config/JobTests.java

@@ -6,6 +6,7 @@
 package org.elasticsearch.xpack.core.ml.job.config;
 
 import com.carrotsearch.randomizedtesting.generators.CodepointSetGenerator;
+
 import org.elasticsearch.ElasticsearchStatusException;
 import org.elasticsearch.Version;
 import org.elasticsearch.common.bytes.BytesReference;
@@ -17,6 +18,7 @@ import org.elasticsearch.common.xcontent.DeprecationHandler;
 import org.elasticsearch.common.xcontent.NamedXContentRegistry;
 import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.common.xcontent.XContentHelper;
+import org.elasticsearch.common.xcontent.XContentParseException;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.XContentType;
 import org.elasticsearch.test.AbstractSerializingTestCase;
@@ -78,9 +80,9 @@ public class JobTests extends AbstractSerializingTestCase<Job> {
     public void testFutureConfigParse() throws IOException {
         XContentParser parser = XContentFactory.xContent(XContentType.JSON)
                 .createParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, FUTURE_JOB);
-        IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
+        XContentParseException e = expectThrows(XContentParseException.class,
                 () -> Job.CONFIG_PARSER.apply(parser, null).build());
-        assertEquals("[job_details] unknown field [tomorrows_technology_today], parser not found", e.getMessage());
+        assertEquals("[4:5] [job_details] unknown field [tomorrows_technology_today], parser not found", e.getMessage());
     }
 
     public void testFutureMetadataParse() throws IOException {

+ 3 - 4
x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/process/autodetect/output/AutodetectResultsParserTests.java

@@ -6,14 +6,13 @@
 package org.elasticsearch.xpack.ml.job.process.autodetect.output;
 
 import org.elasticsearch.ElasticsearchParseException;
-import org.elasticsearch.common.ParsingException;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.xcontent.XContentParseException;
 import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.xpack.core.ml.job.process.autodetect.state.Quantiles;
-import org.elasticsearch.xpack.ml.job.results.AutodetectResult;
 import org.elasticsearch.xpack.core.ml.job.results.Bucket;
 import org.elasticsearch.xpack.core.ml.job.results.BucketInfluencer;
+import org.elasticsearch.xpack.ml.job.results.AutodetectResult;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
@@ -389,9 +388,9 @@ public class AutodetectResultsParserTests extends ESTestCase {
         String json = "[{\"unknown\":{\"id\": 18}}]";
         InputStream inputStream = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8));
         AutodetectResultsParser parser = new AutodetectResultsParser(Settings.EMPTY);
-        IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
+        XContentParseException e = expectThrows(XContentParseException.class,
                 () -> parser.parseResults(inputStream).forEachRemaining(a -> {}));
-        assertEquals("[autodetect_result] unknown field [unknown], parser not found", e.getMessage());
+        assertEquals("[1:3] [autodetect_result] unknown field [unknown], parser not found", e.getMessage());
     }
 
     public void testParse_GivenArrayContainsAnotherArray() throws ElasticsearchParseException, IOException {

+ 5 - 12
x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/common/text/TextTemplateTests.java

@@ -8,6 +8,7 @@ package org.elasticsearch.xpack.watcher.common.text;
 import org.elasticsearch.common.bytes.BytesReference;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentParseException;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.json.JsonXContent;
 import org.elasticsearch.script.Script;
@@ -172,12 +173,8 @@ public class TextTemplateTests extends ESTestCase {
         BytesReference bytes = BytesReference.bytes(builder);
         XContentParser parser = createParser(JsonXContent.jsonXContent, bytes);
         parser.nextToken();
-        try {
-            TextTemplate.parse(parser);
-            fail("expected parse exception when script type is unknown");
-        } catch (IllegalArgumentException e) {
-            assertThat(e.getMessage(), is("[script] unknown field [template], parser not found"));
-        }
+        XContentParseException ex = expectThrows(XContentParseException.class, () -> TextTemplate.parse(parser));
+        assertEquals("[1:2] [script] unknown field [template], parser not found", ex.getMessage());
     }
 
     public void testParserInvalidMissingText() throws Exception {
@@ -188,12 +185,8 @@ public class TextTemplateTests extends ESTestCase {
         BytesReference bytes = BytesReference.bytes(builder);
         XContentParser parser = createParser(JsonXContent.jsonXContent, bytes);
         parser.nextToken();
-        try {
-            TextTemplate.parse(parser);
-            fail("expected parse exception when template text is missing");
-        } catch (IllegalArgumentException e) {
-            assertThat(e.getMessage(), containsString("[script] unknown field [type], parser not found"));
-        }
+        XContentParseException ex = expectThrows(XContentParseException.class, () -> TextTemplate.parse(parser));
+        assertEquals("[1:2] [script] unknown field [type], parser not found", ex.getMessage());
     }
 
     public void testNullObject() throws Exception {