Skip to content

Commit

Permalink
Change ObjectParser exception (#31030)
Browse files Browse the repository at this point in the history
ObjectParser should throw XContentParseExceptions, not IAE. A dedicated parsing
exception can includes the place where the error occurred.

Closes #30605
  • Loading branch information
Christoph Büscher authored Jun 4, 2018
1 parent abe6115 commit 3f87c79
Show file tree
Hide file tree
Showing 18 changed files with 87 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public Value parse(XContentParser parser, Value value, Context context) throws I
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");
Expand Down Expand Up @@ -341,10 +341,11 @@ private void parseSub(XContentParser parser, FieldParser fieldParser, String cur
}
}

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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
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;

Expand Down Expand Up @@ -186,7 +185,6 @@ public URI parseURI(XContentParser parser) {
}

public void testExceptions() throws IOException {
XContentParser parser = createParser(JsonXContent.jsonXContent, "{\"test\" : \"foo\"}");
class TestStruct {
public void setTest(int test) {
}
Expand All @@ -195,20 +193,16 @@ public void setTest(int test) {
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");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,6 @@ protected void doAssertLuceneQuery(FeatureQueryBuilder queryBuilder, Query query
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" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
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;
Expand All @@ -41,7 +42,7 @@
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 {

Expand Down Expand Up @@ -280,9 +281,9 @@ public void testXContentParsingIsNotLenient() throws IOException {
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"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
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;
Expand All @@ -41,7 +42,7 @@

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 {

Expand Down Expand Up @@ -189,9 +190,9 @@ public void testXContentParsingIsNotLenient() throws IOException {
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"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
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;
Expand All @@ -41,7 +42,7 @@

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 {

Expand Down Expand Up @@ -203,8 +204,8 @@ public void testXContentParsingIsNotLenient() throws IOException {
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"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
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;
Expand All @@ -33,7 +34,7 @@

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 {

Expand All @@ -59,8 +60,8 @@ public void testXContentParsingIsNotLenient() throws IOException {
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"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

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;
Expand All @@ -29,7 +30,8 @@
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 {

Expand All @@ -51,10 +53,10 @@ private void doFromXContentTestWithRandomFields(boolean addRandomFields) throws
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
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;
Expand Down Expand Up @@ -70,6 +71,7 @@ public class UpdateRequestTests extends ESTestCase {

private UpdateHelper updateHelper;

@Override
@Before
public void setUp() throws Exception {
super.setUp();
Expand Down Expand Up @@ -283,8 +285,8 @@ public void testUnknownFieldParsing() throws Exception {
.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()
Expand All @@ -294,8 +296,8 @@ public void testUnknownFieldParsing() throws Exception {
.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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,10 @@ public void testFromXContent() throws IOException {
*/
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());
}

{
Expand All @@ -174,7 +174,7 @@ public void testUnknownArrayNameExpection() throws IOException {
"}\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());
}
}

Expand All @@ -188,10 +188,10 @@ private <T extends Throwable> T expectParseThrows(Class<T> exceptionClass, Strin
*/
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());
}

{
Expand All @@ -204,7 +204,7 @@ public void testUnknownFieldnameExpection() throws IOException {
"}\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());
}
}

Expand All @@ -213,10 +213,10 @@ public void testUnknownFieldnameExpection() throws IOException {
*/
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());
}

{
Expand All @@ -229,7 +229,7 @@ public void testUnknownObjectFieldnameExpection() throws IOException {
"}\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());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ public void testRescoreQueryNull() throws IOException {

class AlwaysRewriteQueryBuilder extends MatchAllQueryBuilder {

@Override
protected QueryBuilder doRewrite(QueryRewriteContext queryShardContext) throws IOException {
return new MatchAllQueryBuilder();
}
Expand Down Expand Up @@ -254,8 +255,8 @@ public void testUnknownFieldsExpection() throws IOException {
"}\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" +
Expand Down
Loading

0 comments on commit 3f87c79

Please sign in to comment.