diff --git a/server/src/main/java/org/elasticsearch/common/xcontent/AbstractObjectParser.java b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/AbstractObjectParser.java similarity index 93% rename from server/src/main/java/org/elasticsearch/common/xcontent/AbstractObjectParser.java rename to libs/x-content/src/main/java/org/elasticsearch/common/xcontent/AbstractObjectParser.java index aeb4e53690a69..d2a0e16318060 100644 --- a/server/src/main/java/org/elasticsearch/common/xcontent/AbstractObjectParser.java +++ b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/AbstractObjectParser.java @@ -21,10 +21,8 @@ import org.elasticsearch.common.CheckedFunction; import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.xcontent.ObjectParser.NamedObjectParser; import org.elasticsearch.common.xcontent.ObjectParser.ValueType; -import org.elasticsearch.common.xcontent.json.JsonXContent; import java.io.IOException; import java.util.ArrayList; @@ -214,17 +212,6 @@ public void declareFieldArray(BiConsumer> consumer, ContextPa declareField(consumer, (p, c) -> parseArray(p, () -> itemParser.parse(p, c)), field, type); } - public void declareRawObject(BiConsumer consumer, ParseField field) { - CheckedFunction bytesParser = p -> { - try (XContentBuilder builder = JsonXContent.contentBuilder()) { - builder.prettyPrint(); - builder.copyCurrentStructure(p); - return BytesReference.bytes(builder); - } - }; - declareField(consumer, bytesParser, field, ValueType.OBJECT); - } - private interface IOSupplier { T get() throws IOException; } diff --git a/server/src/main/java/org/elasticsearch/common/xcontent/ConstructingObjectParser.java b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ConstructingObjectParser.java similarity index 97% rename from server/src/main/java/org/elasticsearch/common/xcontent/ConstructingObjectParser.java rename to libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ConstructingObjectParser.java index 03f6b14f525ec..d61bd8a5dbbdb 100644 --- a/server/src/main/java/org/elasticsearch/common/xcontent/ConstructingObjectParser.java +++ b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ConstructingObjectParser.java @@ -20,7 +20,6 @@ package org.elasticsearch.common.xcontent; import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.xcontent.ObjectParser.NamedObjectParser; import org.elasticsearch.common.xcontent.ObjectParser.ValueType; @@ -161,7 +160,7 @@ public Value apply(XContentParser parser, Context context) { try { return parse(parser, context); } catch (IOException e) { - throw new ParsingException(parser.getTokenLocation(), "[" + objectParser.getName() + "] failed to parse object", e); + throw new XContentParseException(parser.getTokenLocation(), "[" + objectParser.getName() + "] failed to parse object", e); } } @@ -335,7 +334,7 @@ private BiConsumer queueingConsumer(BiConsumer consumer try { consumer.accept(targetObject, v); } catch (Exception e) { - throw new ParsingException(location, + throw new XContentParseException(location, "[" + objectParser.getName() + "] failed to parse field [" + parseField.getPreferredName() + "]", e); } }); @@ -413,7 +412,7 @@ private void constructorArg(int position, ParseField parseField, Object value) { private void queue(Consumer queueMe) { assert targetObject == null: "Don't queue after the targetObject has been built! Just apply the consumer directly."; if (queuedFields == null) { - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) Consumer[] queuedFields = new Consumer[numberOfFields]; this.queuedFields = queuedFields; } @@ -471,11 +470,12 @@ private void buildTarget() { queuedFieldsCount -= 1; queuedFields[queuedFieldsCount].accept(targetObject); } - } catch (ParsingException e) { - throw new ParsingException(e.getLineNumber(), e.getColumnNumber(), - "failed to build [" + objectParser.getName() + "] after last required field arrived", e); + } catch (XContentParseException e) { + throw new XContentParseException(e.getLocation(), + "failed to build [" + objectParser.getName() + "] after last required field arrived", e); } catch (Exception e) { - throw new ParsingException(null, "Failed to build [" + objectParser.getName() + "] after last required field arrived", e); + throw new XContentParseException(null, + "Failed to build [" + objectParser.getName() + "] after last required field arrived", e); } } } diff --git a/server/src/main/java/org/elasticsearch/common/xcontent/ObjectParser.java b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ObjectParser.java similarity index 93% rename from server/src/main/java/org/elasticsearch/common/xcontent/ObjectParser.java rename to libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ObjectParser.java index 1a3be1a5a7bdd..71b888bf44acb 100644 --- a/server/src/main/java/org/elasticsearch/common/xcontent/ObjectParser.java +++ b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ObjectParser.java @@ -20,7 +20,6 @@ import org.elasticsearch.common.Nullable; import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.ParsingException; import java.io.IOException; import java.lang.reflect.Array; @@ -147,7 +146,7 @@ public Value parse(XContentParser parser, Value value, Context context) throws I } else { token = parser.nextToken(); if (token != XContentParser.Token.START_OBJECT) { - throw new ParsingException(parser.getTokenLocation(), "[" + name + "] Expected START_OBJECT but was: " + token); + throw new XContentParseException(parser.getTokenLocation(), "[" + name + "] Expected START_OBJECT but was: " + token); } } @@ -159,7 +158,7 @@ public Value parse(XContentParser parser, Value value, Context context) throws I fieldParser = getParser(currentFieldName); } else { if (currentFieldName == null) { - throw new ParsingException(parser.getTokenLocation(), "[" + name + "] no field found"); + throw new XContentParseException(parser.getTokenLocation(), "[" + name + "] no field found"); } if (fieldParser == null) { assert ignoreUnknownFields : "this should only be possible if configured to ignore known fields"; @@ -182,7 +181,7 @@ public Value apply(XContentParser parser, Context context) { try { return parse(parser, valueSupplier.get(), context); } catch (IOException e) { - throw new ParsingException(parser.getTokenLocation(), "[" + name + "] failed to parse object", e); + throw new XContentParseException(parser.getTokenLocation(), "[" + name + "] failed to parse object", e); } } @@ -233,7 +232,7 @@ public void declareNamedObjects(BiConsumer> consumer, NamedOb // This creates and parses the named object BiFunction objectParser = (XContentParser p, Context c) -> { if (p.currentToken() != XContentParser.Token.FIELD_NAME) { - throw new ParsingException(p.getTokenLocation(), "[" + field + "] can be a single object with any number of " + throw new XContentParseException(p.getTokenLocation(), "[" + field + "] can be a single object with any number of " + "fields or an array where each entry is an object with a single field"); } // This messy exception nesting has the nice side effect of telling the use which field failed to parse @@ -242,10 +241,10 @@ public void declareNamedObjects(BiConsumer> consumer, NamedOb try { return namedObjectParser.parse(p, c, name); } catch (Exception e) { - throw new ParsingException(p.getTokenLocation(), "[" + field + "] failed to parse field [" + name + "]", e); + throw new XContentParseException(p.getTokenLocation(), "[" + field + "] failed to parse field [" + name + "]", e); } } catch (IOException e) { - throw new ParsingException(p.getTokenLocation(), "[" + field + "] error while parsing", e); + throw new XContentParseException(p.getTokenLocation(), "[" + field + "] error while parsing", e); } }; declareField((XContentParser p, Value v, Context c) -> { @@ -261,14 +260,14 @@ public void declareNamedObjects(BiConsumer> consumer, NamedOb orderedModeCallback.accept(v); while ((token = p.nextToken()) != XContentParser.Token.END_ARRAY) { if (token != XContentParser.Token.START_OBJECT) { - throw new ParsingException(p.getTokenLocation(), "[" + field + "] can be a single object with any number of " + throw new XContentParseException(p.getTokenLocation(), "[" + field + "] can be a single object with any number of " + "fields or an array where each entry is an object with a single field"); } p.nextToken(); // Move to the first field in the object fields.add(objectParser.apply(p, c)); p.nextToken(); // Move past the object, should be back to into the array if (p.currentToken() != XContentParser.Token.END_OBJECT) { - throw new ParsingException(p.getTokenLocation(), "[" + field + "] can be a single object with any number of " + throw new XContentParseException(p.getTokenLocation(), "[" + field + "] can be a single object with any number of " + "fields or an array where each entry is an object with a single field"); } } @@ -314,7 +313,8 @@ private void parseValue(XContentParser parser, FieldParser fieldParser, String c try { fieldParser.parser.parse(parser, value, context); } catch (Exception ex) { - throw new ParsingException(parser.getTokenLocation(), "[" + name + "] failed to parse field [" + currentFieldName + "]", ex); + throw new XContentParseException(parser.getTokenLocation(), + "[" + name + "] failed to parse field [" + currentFieldName + "]", ex); } } @@ -331,7 +331,7 @@ private void parseSub(XContentParser parser, FieldParser fieldParser, String cur case END_OBJECT: case END_ARRAY: case FIELD_NAME: - throw new ParsingException(parser.getTokenLocation(), "[" + name + "]" + token + " is unexpected"); + throw new XContentParseException(parser.getTokenLocation(), "[" + name + "]" + token + " is unexpected"); case VALUE_STRING: case VALUE_NUMBER: case VALUE_BOOLEAN: @@ -364,11 +364,11 @@ private class FieldParser { void assertSupports(String parserName, XContentParser parser, String currentFieldName) { if (parseField.match(currentFieldName, parser.getDeprecationHandler()) == false) { - throw new ParsingException(parser.getTokenLocation(), + throw new XContentParseException(parser.getTokenLocation(), "[" + parserName + "] parsefield doesn't accept: " + currentFieldName); } if (supportedTokens.contains(parser.currentToken()) == false) { - throw new ParsingException(parser.getTokenLocation(), + throw new XContentParseException(parser.getTokenLocation(), "[" + parserName + "] " + currentFieldName + " doesn't support values of type: " + parser.currentToken()); } } diff --git a/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/XContentParseException.java b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/XContentParseException.java index cd2e3dbb59baa..69c345d20c2a6 100644 --- a/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/XContentParseException.java +++ b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/XContentParseException.java @@ -19,6 +19,8 @@ package org.elasticsearch.common.xcontent; +import org.elasticsearch.common.Nullable; + import java.util.Optional; /** @@ -37,6 +39,11 @@ public XContentParseException(XContentLocation location, String message) { this.location = Optional.ofNullable(location); } + public XContentParseException(XContentLocation location, String message, Exception cause) { + super(message, cause); + this.location = Optional.ofNullable(location); + } + public int getLineNumber() { return location.map(l -> l.lineNumber).orElse(-1); } @@ -45,8 +52,14 @@ public int getColumnNumber() { return location.map(l -> l.columnNumber).orElse(-1); } + @Nullable + public XContentLocation getLocation() { + return location.orElse(null); + } + @Override public String getMessage() { return location.map(l -> "[" + l.toString() + "] ").orElse("") + super.getMessage(); } + } diff --git a/server/src/test/java/org/elasticsearch/common/xcontent/ConstructingObjectParserTests.java b/libs/x-content/src/test/java/org/elasticsearch/common/xcontent/ConstructingObjectParserTests.java similarity index 84% rename from server/src/test/java/org/elasticsearch/common/xcontent/ConstructingObjectParserTests.java rename to libs/x-content/src/test/java/org/elasticsearch/common/xcontent/ConstructingObjectParserTests.java index 9f24861fdaa0e..7488cfd7e9c55 100644 --- a/server/src/test/java/org/elasticsearch/common/xcontent/ConstructingObjectParserTests.java +++ b/libs/x-content/src/test/java/org/elasticsearch/common/xcontent/ConstructingObjectParserTests.java @@ -22,14 +22,12 @@ import org.elasticsearch.common.CheckedFunction; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.ParsingException; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.xcontent.ObjectParserTests.NamedObject; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.test.ESTestCase; import org.hamcrest.Matcher; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.List; @@ -38,6 +36,7 @@ import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg; import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg; import static org.hamcrest.Matchers.anyOf; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.instanceOf; @@ -79,7 +78,8 @@ public void testRandomOrder() throws Exception { XContentBuilder builder = XContentFactory.jsonBuilder().prettyPrint(); expected.toXContent(builder, ToXContent.EMPTY_PARAMS); builder = shuffleXContent(builder); - BytesReference bytes = BytesReference.bytes(builder); + builder.flush(); + byte[] bytes = ((ByteArrayOutputStream) builder.getOutputStream()).toByteArray(); try (XContentParser parser = createParser(JsonXContent.jsonXContent, bytes)) { HasCtorArguments parsed = randomFrom(HasCtorArguments.ALL_PARSERS).apply(parser, null); assertEquals(expected.animal, parsed.animal); @@ -90,9 +90,6 @@ public void testRandomOrder() throws Exception { assertEquals(expected.b, parsed.b); assertEquals(expected.c, parsed.c); assertEquals(expected.d, parsed.d); - } catch (Exception e) { - // It is convenient to decorate the error message with the json - throw new Exception("Error parsing: [" + Strings.toString(builder) + "]", e); } } @@ -175,7 +172,7 @@ public void testRepeatedConstructorParam() throws IOException { + " \"vegetable\": 1,\n" + " \"vegetable\": 2\n" + "}"); - Throwable e = expectThrows(ParsingException.class, () -> randomFrom(HasCtorArguments.ALL_PARSERS).apply(parser, null)); + Throwable e = expectThrows(XContentParseException.class, () -> randomFrom(HasCtorArguments.ALL_PARSERS).apply(parser, null)); assertEquals("[has_required_arguments] failed to parse field [vegetable]", e.getMessage()); e = e.getCause(); assertThat(e, instanceOf(IllegalArgumentException.class)); @@ -189,8 +186,9 @@ public void testBadParam() throws IOException { + " \"vegetable\": 2,\n" + " \"a\": \"supercalifragilisticexpialidocious\"\n" + "}"); - ParsingException e = expectThrows(ParsingException.class, () -> randomFrom(HasCtorArguments.ALL_PARSERS).apply(parser, null)); - assertEquals("[has_required_arguments] failed to parse field [a]", e.getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, + () -> randomFrom(HasCtorArguments.ALL_PARSERS).apply(parser, null)); + assertThat(e.getMessage(), containsString("[has_required_arguments] failed to parse field [a]")); assertEquals(4, e.getLineNumber()); assertEquals("[a] must be less than 10 characters in length but was [supercalifragilisticexpialidocious]", e.getCause().getMessage()); @@ -203,14 +201,15 @@ public void testBadParamBeforeObjectBuilt() throws IOException { + " \"animal\": \"cat\"\n," + " \"vegetable\": 2\n" + "}"); - ParsingException e = expectThrows(ParsingException.class, () -> randomFrom(HasCtorArguments.ALL_PARSERS).apply(parser, null)); - assertEquals("[has_required_arguments] failed to parse field [vegetable]", e.getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, + () -> randomFrom(HasCtorArguments.ALL_PARSERS).apply(parser, null)); + assertThat(e.getMessage(), containsString("[has_required_arguments] failed to parse field [vegetable]")); assertEquals(4, e.getLineNumber()); - e = (ParsingException) e.getCause(); - assertEquals("failed to build [has_required_arguments] after last required field arrived", e.getMessage()); + e = (XContentParseException) e.getCause(); + assertThat(e.getMessage(), containsString("failed to build [has_required_arguments] after last required field arrived")); assertEquals(2, e.getLineNumber()); - e = (ParsingException) e.getCause(); - assertEquals("[has_required_arguments] failed to parse field [a]", e.getMessage()); + e = (XContentParseException) e.getCause(); + assertThat(e.getMessage(), containsString("[has_required_arguments] failed to parse field [a]")); assertEquals(2, e.getLineNumber()); assertEquals("[a] must be less than 10 characters in length but was [supercalifragilisticexpialidocious]", e.getCause().getMessage()); @@ -465,11 +464,11 @@ public void testParseNamedObjectTwoFieldsInArray() throws IOException { + "],\"named_in_constructor\": [\n" + " {\"c\": {}}" + "]}"); - ParsingException e = expectThrows(ParsingException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); - assertEquals("[named_object_holder] failed to parse field [named]", e.getMessage()); - assertEquals( - "[named] can be a single object with any number of fields or an array where each entry is an object with a single field", - e.getCause().getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); + assertThat(e.getMessage(), containsString("[named_object_holder] failed to parse field [named]")); + assertThat(e.getCause().getMessage(), + containsString("[named] can be a single object with any number of fields " + + "or an array where each entry is an object with a single field")); } public void testParseNamedObjectTwoFieldsInArrayConstructorArg() throws IOException { @@ -479,11 +478,11 @@ public void testParseNamedObjectTwoFieldsInArrayConstructorArg() throws IOExcept + "],\"named_in_constructor\": [\n" + " {\"c\": {}, \"d\": {}}" + "]}"); - ParsingException e = expectThrows(ParsingException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); - assertEquals("[named_object_holder] failed to parse field [named_in_constructor]", e.getMessage()); - assertEquals( - "[named_in_constructor] can be a single object with any number of fields or an array where each entry is an object with a " - + "single field", e.getCause().getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); + assertThat(e.getMessage(), containsString("[named_object_holder] failed to parse field [named_in_constructor]")); + assertThat(e.getCause().getMessage(), + containsString("[named_in_constructor] can be a single object with any number of fields " + + "or an array where each entry is an object with a single field")); } public void testParseNamedObjectNoFieldsInArray() throws IOException { @@ -493,11 +492,11 @@ public void testParseNamedObjectNoFieldsInArray() throws IOException { + "],\"named_in_constructor\": [\n" + " {\"a\": {}}" + "]}"); - ParsingException e = expectThrows(ParsingException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); - assertEquals("[named_object_holder] failed to parse field [named]", e.getMessage()); - assertEquals( - "[named] can be a single object with any number of fields or an array where each entry is an object with a single field", - e.getCause().getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); + assertThat(e.getMessage(), containsString("[named_object_holder] failed to parse field [named]")); + assertThat(e.getCause().getMessage(), + containsString("[named] can be a single object with any number of fields " + + "or an array where each entry is an object with a single field")); } public void testParseNamedObjectNoFieldsInArrayConstructorArg() throws IOException { @@ -507,11 +506,11 @@ public void testParseNamedObjectNoFieldsInArrayConstructorArg() throws IOExcepti + "],\"named_in_constructor\": [\n" + " {}" + "]}"); - ParsingException e = expectThrows(ParsingException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); - assertEquals("[named_object_holder] failed to parse field [named_in_constructor]", e.getMessage()); - assertEquals( - "[named_in_constructor] can be a single object with any number of fields or an array where each entry is an object with a " - + "single field", e.getCause().getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); + assertThat(e.getMessage(), containsString("[named_object_holder] failed to parse field [named_in_constructor]")); + assertThat(e.getCause().getMessage(), + containsString("[named_in_constructor] can be a single object with any number of fields " + + "or an array where each entry is an object with a single field")); } public void testParseNamedObjectJunkInArray() throws IOException { @@ -521,11 +520,11 @@ public void testParseNamedObjectJunkInArray() throws IOException { + "],\"named_in_constructor\": [\n" + " {\"a\": {}}" + "]}"); - ParsingException e = expectThrows(ParsingException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); - assertEquals("[named_object_holder] failed to parse field [named]", e.getMessage()); - assertEquals( - "[named] can be a single object with any number of fields or an array where each entry is an object with a single field", - e.getCause().getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); + assertThat(e.getMessage(), containsString("[named_object_holder] failed to parse field [named]")); + assertThat(e.getCause().getMessage(), + containsString("[named] can be a single object with any number of fields " + + "or an array where each entry is an object with a single field")); } public void testParseNamedObjectJunkInArrayConstructorArg() throws IOException { @@ -535,11 +534,11 @@ public void testParseNamedObjectJunkInArrayConstructorArg() throws IOException { + "],\"named_in_constructor\": [\n" + " \"junk\"" + "]}"); - ParsingException e = expectThrows(ParsingException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); - assertEquals("[named_object_holder] failed to parse field [named_in_constructor]", e.getMessage()); - assertEquals( - "[named_in_constructor] can be a single object with any number of fields or an array where each entry is an object with a " - + "single field", e.getCause().getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); + assertThat(e.getMessage(), containsString("[named_object_holder] failed to parse field [named_in_constructor]")); + assertThat(e.getCause().getMessage(), + containsString("[named_in_constructor] can be a single object with any number of fields " + + "or an array where each entry is an object with a single field")); } public void testParseNamedObjectInOrderNotSupported() throws IOException { @@ -558,8 +557,8 @@ public void testParseNamedObjectInOrderNotSupported() throws IOException { objectParser.declareNamedObjects(NamedObjectHolder::setNamed, NamedObject.PARSER, new ParseField("named")); // Now firing the xml through it fails - ParsingException e = expectThrows(ParsingException.class, () -> objectParser.apply(parser, null)); - assertEquals("[named_object_holder] failed to parse field [named]", e.getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, () -> objectParser.apply(parser, null)); + assertThat(e.getMessage(), containsString("[named_object_holder] failed to parse field [named]")); assertEquals("[named] doesn't support arrays. Use a single object with multiple fields.", e.getCause().getMessage()); } @@ -579,9 +578,10 @@ public void testParseNamedObjectInOrderNotSupportedConstructorArg() throws IOExc objectParser.declareNamedObjects(NamedObjectHolder::setNamed, NamedObject.PARSER, new ParseField("named")); // Now firing the xml through it fails - ParsingException e = expectThrows(ParsingException.class, () -> objectParser.apply(parser, null)); - assertEquals("[named_object_holder] failed to parse field [named_in_constructor]", e.getMessage()); - assertEquals("[named_in_constructor] doesn't support arrays. Use a single object with multiple fields.", e.getCause().getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, () -> objectParser.apply(parser, null)); + assertThat(e.getMessage(), containsString("[named_object_holder] failed to parse field [named_in_constructor]")); + assertThat(e.getCause().getMessage(), + containsString("[named_in_constructor] doesn't support arrays. Use a single object with multiple fields.")); } static class NamedObjectHolder { diff --git a/server/src/test/java/org/elasticsearch/common/xcontent/ObjectParserTests.java b/libs/x-content/src/test/java/org/elasticsearch/common/xcontent/ObjectParserTests.java similarity index 92% rename from server/src/test/java/org/elasticsearch/common/xcontent/ObjectParserTests.java rename to libs/x-content/src/test/java/org/elasticsearch/common/xcontent/ObjectParserTests.java index 6f0c0208b9c75..3dd33e997b2ea 100644 --- a/server/src/test/java/org/elasticsearch/common/xcontent/ObjectParserTests.java +++ b/libs/x-content/src/test/java/org/elasticsearch/common/xcontent/ObjectParserTests.java @@ -20,14 +20,13 @@ import org.elasticsearch.common.CheckedFunction; import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.Strings; -import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.xcontent.ObjectParser.NamedObjectParser; import org.elasticsearch.common.xcontent.ObjectParser.ValueType; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.test.ESTestCase; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UncheckedIOException; import java.net.URI; @@ -199,8 +198,8 @@ public void setTest(int test) { try { objectParser.parse(parser, s, null); fail("numeric value expected"); - } catch (ParsingException ex) { - assertEquals(ex.getMessage(), "[the_parser] failed to parse field [test]"); + } catch (XContentParseException ex) { + assertThat(ex.getMessage(), containsString("[the_parser] failed to parse field [test]")); assertTrue(ex.getCause() instanceof NumberFormatException); } @@ -235,7 +234,7 @@ class TestStruct { TestStruct s = new TestStruct(); objectParser.declareField((i, c, x) -> c.test = i.text(), new ParseField("numeric_value"), ObjectParser.ValueType.FLOAT); - Exception e = expectThrows(ParsingException.class, () -> objectParser.parse(parser, s, null)); + Exception e = expectThrows(XContentParseException.class, () -> objectParser.parse(parser, s, null)); assertThat(e.getMessage(), containsString("[foo] numeric_value doesn't support values of type: VALUE_BOOLEAN")); } @@ -478,11 +477,11 @@ public void testParseNamedObjectTwoFieldsInArray() throws IOException { "{\"named\": [\n" + " {\"a\": {}, \"b\": {}}" + "]}"); - ParsingException e = expectThrows(ParsingException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); - assertEquals("[named_object_holder] failed to parse field [named]", e.getMessage()); - assertEquals( - "[named] can be a single object with any number of fields or an array where each entry is an object with a single field", - e.getCause().getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); + assertThat(e.getMessage(), containsString("[named_object_holder] failed to parse field [named]")); + assertThat(e.getCause().getMessage(), + containsString("[named] can be a single object with any number of fields " + + "or an array where each entry is an object with a single field")); } public void testParseNamedObjectNoFieldsInArray() throws IOException { @@ -490,11 +489,11 @@ public void testParseNamedObjectNoFieldsInArray() throws IOException { "{\"named\": [\n" + " {}" + "]}"); - ParsingException e = expectThrows(ParsingException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); - assertEquals("[named_object_holder] failed to parse field [named]", e.getMessage()); - assertEquals( - "[named] can be a single object with any number of fields or an array where each entry is an object with a single field", - e.getCause().getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); + assertThat(e.getMessage(), containsString("[named_object_holder] failed to parse field [named]")); + assertThat(e.getCause().getMessage(), + containsString("[named] can be a single object with any number of fields " + + "or an array where each entry is an object with a single field")); } public void testParseNamedObjectJunkInArray() throws IOException { @@ -502,11 +501,11 @@ public void testParseNamedObjectJunkInArray() throws IOException { "{\"named\": [\n" + " \"junk\"" + "]}"); - ParsingException e = expectThrows(ParsingException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); - assertEquals("[named_object_holder] failed to parse field [named]", e.getMessage()); - assertEquals( - "[named] can be a single object with any number of fields or an array where each entry is an object with a single field", - e.getCause().getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, () -> NamedObjectHolder.PARSER.apply(parser, null)); + assertThat(e.getMessage(), containsString("[named_object_holder] failed to parse field [named]")); + assertThat(e.getCause().getMessage(), + containsString("[named] can be a single object with any number of fields " + + "or an array where each entry is an object with a single field")); } public void testParseNamedObjectInOrderNotSupported() throws IOException { @@ -521,8 +520,8 @@ public void testParseNamedObjectInOrderNotSupported() throws IOException { objectParser.declareNamedObjects(NamedObjectHolder::setNamed, NamedObject.PARSER, new ParseField("named")); // Now firing the xml through it fails - ParsingException e = expectThrows(ParsingException.class, () -> objectParser.apply(parser, null)); - assertEquals("[named_object_holder] failed to parse field [named]", e.getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, () -> objectParser.apply(parser, null)); + assertThat(e.getMessage(), containsString("[named_object_holder] failed to parse field [named]")); assertEquals("[named] doesn't support arrays. Use a single object with multiple fields.", e.getCause().getMessage()); } @@ -535,7 +534,9 @@ public void testIgnoreUnknownFields() throws IOException { } b.endObject(); b = shuffleXContent(b); - XContentParser parser = createParser(JsonXContent.jsonXContent, BytesReference.bytes(b)); + b.flush(); + byte[] bytes = ((ByteArrayOutputStream) b.getOutputStream()).toByteArray(); + XContentParser parser = createParser(JsonXContent.jsonXContent, bytes); class TestStruct { public String test; @@ -559,7 +560,9 @@ public void testIgnoreUnknownObjects() throws IOException { } b.endObject(); b = shuffleXContent(b); - XContentParser parser = createParser(JsonXContent.jsonXContent, BytesReference.bytes(b)); + b.flush(); + byte[] bytes = ((ByteArrayOutputStream) b.getOutputStream()).toByteArray(); + XContentParser parser = createParser(JsonXContent.jsonXContent, bytes); class TestStruct { public String test; @@ -587,7 +590,9 @@ public void testIgnoreUnknownArrays() throws IOException { } b.endObject(); b = shuffleXContent(b); - XContentParser parser = createParser(JsonXContent.jsonXContent, BytesReference.bytes(b)); + b.flush(); + byte[] bytes = ((ByteArrayOutputStream) b.getOutputStream()).toByteArray(); + XContentParser parser = createParser(JsonXContent.jsonXContent, bytes); class TestStruct { public String test; } @@ -646,8 +651,8 @@ public void setArray(List testArray) { // Make sure that we didn't break the null handling in arrays that shouldn't support nulls XContentParser parser2 = createParser(JsonXContent.jsonXContent, "{\"int_array\": [1, null, 3]}"); TestStruct s2 = new TestStruct(); - ParsingException ex = expectThrows(ParsingException.class, () -> objectParser.parse(parser2, s2, null)); - assertThat(ex.getMessage(), startsWith("[foo] failed to parse field [int_array]")); + XContentParseException ex = expectThrows(XContentParseException.class, () -> objectParser.parse(parser2, s2, null)); + assertThat(ex.getMessage(), containsString("[foo] failed to parse field [int_array]")); } static class NamedObjectHolder { diff --git a/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/ScriptProcessorFactoryTests.java b/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/ScriptProcessorFactoryTests.java index f1a7add303f1b..d7f8e8838bb8c 100644 --- a/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/ScriptProcessorFactoryTests.java +++ b/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/ScriptProcessorFactoryTests.java @@ -20,6 +20,7 @@ package org.elasticsearch.ingest.common; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.common.xcontent.XContentParseException; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptException; import org.elasticsearch.script.ScriptService; @@ -30,6 +31,7 @@ import java.util.HashMap; import java.util.Map; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.mockito.Matchers.any; @@ -80,9 +82,9 @@ public void testFactoryValidationForMultipleScriptingTypes() throws Exception { configMap.put("source", "bar"); configMap.put("lang", "mockscript"); - ElasticsearchException exception = expectThrows(ElasticsearchException.class, + XContentParseException exception = expectThrows(XContentParseException.class, () -> factory.create(null, randomAlphaOfLength(10), configMap)); - assertThat(exception.getMessage(), is("[script] failed to parse field [source]")); + assertThat(exception.getMessage(), containsString("[script] failed to parse field [source]")); } public void testFactoryValidationAtLeastOneScriptingType() throws Exception { diff --git a/modules/lang-mustache/src/test/java/org/elasticsearch/script/mustache/SearchTemplateRequestTests.java b/modules/lang-mustache/src/test/java/org/elasticsearch/script/mustache/SearchTemplateRequestTests.java index 51b7df3fc2cae..9cdca70f0e1a6 100644 --- a/modules/lang-mustache/src/test/java/org/elasticsearch/script/mustache/SearchTemplateRequestTests.java +++ b/modules/lang-mustache/src/test/java/org/elasticsearch/script/mustache/SearchTemplateRequestTests.java @@ -19,7 +19,7 @@ package org.elasticsearch.script.mustache; -import org.elasticsearch.common.ParsingException; +import org.elasticsearch.common.xcontent.XContentParseException; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.script.ScriptType; @@ -122,7 +122,7 @@ public void testParseStoredTemplateWithParams() throws Exception { public void testParseWrongTemplate() { // Unclosed template id - expectThrows(ParsingException.class, () -> RestSearchTemplateAction.parse(newParser("{'id' : 'another_temp }"))); + expectThrows(XContentParseException.class, () -> RestSearchTemplateAction.parse(newParser("{'id' : 'another_temp }"))); } /** diff --git a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalSpecTests.java b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalSpecTests.java index 94338e570a5d2..b49811a9bcaec 100644 --- a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalSpecTests.java +++ b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RankEvalSpecTests.java @@ -51,6 +51,7 @@ import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode; import static org.elasticsearch.test.XContentTestUtils.insertRandomFields; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.startsWith; public class RankEvalSpecTests extends ESTestCase { @@ -133,7 +134,7 @@ public void testXContentParsingIsNotLenient() throws IOException { BytesReference withRandomFields = insertRandomFields(xContentType, originalBytes, null, random()); try (XContentParser parser = createParser(xContentType.xContent(), withRandomFields)) { Exception exception = expectThrows(Exception.class, () -> RankEvalSpec.parse(parser)); - assertThat(exception.getMessage(), startsWith("[rank_eval] failed to parse field")); + assertThat(exception.getMessage(), containsString("[rank_eval] failed to parse field")); } } diff --git a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RatedRequestsTests.java b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RatedRequestsTests.java index 0f23178c68391..ad962178f581f 100644 --- a/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RatedRequestsTests.java +++ b/modules/rank-eval/src/test/java/org/elasticsearch/index/rankeval/RatedRequestsTests.java @@ -19,6 +19,7 @@ package org.elasticsearch.index.rankeval; +import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; @@ -27,6 +28,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; @@ -51,6 +53,7 @@ import static java.util.stream.Collectors.toList; import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode; import static org.elasticsearch.test.XContentTestUtils.insertRandomFields; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.startsWith; public class RatedRequestsTests extends ESTestCase { @@ -134,11 +137,13 @@ public void testXContentParsingIsNotLenient() throws IOException { BytesReference withRandomFields = insertRandomFields(xContentType, originalBytes, null, random()); try (XContentParser parser = createParser(xContentType.xContent(), withRandomFields)) { Exception exception = expectThrows(Exception.class, () -> RatedRequest.fromXContent(parser)); - if (exception instanceof IllegalArgumentException) { - assertThat(exception.getMessage(), startsWith("[request] unknown field")); + if (exception instanceof XContentParseException) { + XContentParseException xcpe = (XContentParseException) exception; + assertThat(ExceptionsHelper.detailedMessage(xcpe), containsString("unknown field")); + assertThat(ExceptionsHelper.detailedMessage(xcpe), containsString("parser not found")); } - if (exception instanceof ParsingException) { - assertThat(exception.getMessage(), startsWith("[request] failed to parse field")); + if (exception instanceof XContentParseException) { + assertThat(exception.getMessage(), containsString("[request] failed to parse field")); } } } diff --git a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/remote/RemoteScrollableHitSource.java b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/remote/RemoteScrollableHitSource.java index 80419a9b9d7a2..566c97c61c455 100644 --- a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/remote/RemoteScrollableHitSource.java +++ b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/remote/RemoteScrollableHitSource.java @@ -31,6 +31,7 @@ import org.elasticsearch.Version; import org.elasticsearch.action.bulk.BackoffPolicy; import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; +import org.elasticsearch.common.xcontent.XContentParseException; import org.elasticsearch.index.reindex.ScrollableHitSource; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.client.ResponseException; @@ -199,7 +200,7 @@ public void onSuccess(org.elasticsearch.client.Response response) { try (XContentParser xContentParser = xContentType.xContent().createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, content)) { parsedResponse = parser.apply(xContentParser, xContentType); - } catch (ParsingException e) { + } catch (XContentParseException e) { /* Because we're streaming the response we can't get a copy of it here. The best we can do is hint that it * is totally wrong and we're probably not talking to Elasticsearch. */ throw new ElasticsearchException( diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/160_extended_stats_metric.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/160_extended_stats_metric.yml index aff30d17de167..6ad8166a6a8a3 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/160_extended_stats_metric.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/160_extended_stats_metric.yml @@ -281,7 +281,7 @@ setup: sigma: -1 - do: - catch: /parsing_exception/ + catch: /x_content_parse_exception/ search: body: aggs: diff --git a/server/src/main/java/org/elasticsearch/common/xcontent/ObjectParserHelper.java b/server/src/main/java/org/elasticsearch/common/xcontent/ObjectParserHelper.java new file mode 100644 index 0000000000000..b40b981981901 --- /dev/null +++ b/server/src/main/java/org/elasticsearch/common/xcontent/ObjectParserHelper.java @@ -0,0 +1,52 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.common.xcontent; + +import org.elasticsearch.common.CheckedFunction; +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.xcontent.ObjectParser.ValueType; +import org.elasticsearch.common.xcontent.json.JsonXContent; + +import java.io.IOException; +import java.util.function.BiConsumer; + +/** + * This class provides helpers for {@link ObjectParser} that allow dealing with + * classes outside of the xcontent dependencies. + */ +public final class ObjectParserHelper { + + /** + * Helper to declare an object that will be parsed into a {@link BytesReference} + */ + public void declareRawObject(final AbstractObjectParser parser, + final BiConsumer consumer, + final ParseField field) { + final CheckedFunction bytesParser = p -> { + try (XContentBuilder builder = JsonXContent.contentBuilder()) { + builder.copyCurrentStructure(p); + return BytesReference.bytes(builder); + } + }; + parser.declareField(consumer, bytesParser, field, ValueType.OBJECT); + } + +} diff --git a/server/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryQueryContext.java b/server/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryQueryContext.java index e639fb07844e5..e391f78f27c50 100644 --- a/server/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryQueryContext.java +++ b/server/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryQueryContext.java @@ -19,12 +19,11 @@ package org.elasticsearch.search.suggest.completion.context; -import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.xcontent.ObjectParser; import org.elasticsearch.common.xcontent.ToXContentObject; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParseException; import org.elasticsearch.common.xcontent.XContentParser; import java.io.IOException; @@ -110,14 +109,14 @@ public static CategoryQueryContext fromXContent(XContentParser parser) throws IO if (token == XContentParser.Token.START_OBJECT) { try { CATEGORY_PARSER.parse(parser, builder, null); - } catch(ParsingException e) { - throw new ElasticsearchParseException("category context must be a string, number or boolean"); + } catch(XContentParseException e) { + throw new XContentParseException("category context must be a string, number or boolean"); } } else if (token == XContentParser.Token.VALUE_STRING || token == XContentParser.Token.VALUE_BOOLEAN || token == XContentParser.Token.VALUE_NUMBER) { builder.setCategory(parser.text()); } else { - throw new ElasticsearchParseException("category context must be an object, string, number or boolean"); + throw new XContentParseException("category context must be an object, string, number or boolean"); } return builder.build(); } diff --git a/server/src/main/java/org/elasticsearch/tasks/TaskInfo.java b/server/src/main/java/org/elasticsearch/tasks/TaskInfo.java index 9027f961ae75b..da4909bb3817f 100644 --- a/server/src/main/java/org/elasticsearch/tasks/TaskInfo.java +++ b/server/src/main/java/org/elasticsearch/tasks/TaskInfo.java @@ -28,6 +28,7 @@ import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.ConstructingObjectParser; +import org.elasticsearch.common.xcontent.ObjectParserHelper; import org.elasticsearch.common.xcontent.ToXContent.Params; import org.elasticsearch.common.xcontent.ToXContentFragment; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -242,7 +243,8 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws PARSER.declareString(constructorArg(), new ParseField("type")); PARSER.declareString(constructorArg(), new ParseField("action")); PARSER.declareString(optionalConstructorArg(), new ParseField("description")); - PARSER.declareRawObject(optionalConstructorArg(), new ParseField("status")); + ObjectParserHelper parserHelper = new ObjectParserHelper<>(); + parserHelper.declareRawObject(PARSER, optionalConstructorArg(), new ParseField("status")); PARSER.declareLong(constructorArg(), new ParseField("start_time_in_millis")); PARSER.declareLong(constructorArg(), new ParseField("running_time_in_nanos")); PARSER.declareBoolean(constructorArg(), new ParseField("cancellable")); diff --git a/server/src/main/java/org/elasticsearch/tasks/TaskResult.java b/server/src/main/java/org/elasticsearch/tasks/TaskResult.java index f75a4fe7ee520..a866ad9bb2dd1 100644 --- a/server/src/main/java/org/elasticsearch/tasks/TaskResult.java +++ b/server/src/main/java/org/elasticsearch/tasks/TaskResult.java @@ -28,6 +28,7 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.xcontent.ConstructingObjectParser; +import org.elasticsearch.common.xcontent.ObjectParserHelper; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContentObject; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -185,8 +186,9 @@ public XContentBuilder innerToXContent(XContentBuilder builder, Params params) t static { PARSER.declareBoolean(constructorArg(), new ParseField("completed")); PARSER.declareObject(constructorArg(), TaskInfo.PARSER, new ParseField("task")); - PARSER.declareRawObject(optionalConstructorArg(), new ParseField("error")); - PARSER.declareRawObject(optionalConstructorArg(), new ParseField("response")); + ObjectParserHelper parserHelper = new ObjectParserHelper<>(); + parserHelper.declareRawObject(PARSER, optionalConstructorArg(), new ParseField("error")); + parserHelper.declareRawObject(PARSER, optionalConstructorArg(), new ParseField("response")); } @Override diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/AliasActionsTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/AliasActionsTests.java index 1811bfb89a62d..fcd73a6f1dda3 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/alias/AliasActionsTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/alias/AliasActionsTests.java @@ -28,6 +28,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; @@ -42,6 +43,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.Matchers.arrayContaining; import static org.hamcrest.Matchers.arrayWithSize; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.instanceOf; public class AliasActionsTests extends ESTestCase { @@ -265,9 +267,9 @@ public void testParseIndexAndIndicesThrowsError() throws IOException { } b.endObject(); try (XContentParser parser = createParser(b)) { - Exception e = expectThrows(ParsingException.class, () -> AliasActions.PARSER.apply(parser, null)); + Exception e = expectThrows(XContentParseException.class, () -> AliasActions.PARSER.apply(parser, null)); assertThat(e.getCause().getCause(), instanceOf(IllegalArgumentException.class)); - assertEquals("Only one of [index] and [indices] is supported", e.getCause().getCause().getMessage()); + assertThat(e.getCause().getCause().getMessage(), containsString("Only one of [index] and [indices] is supported")); } } @@ -285,9 +287,9 @@ public void testParseAliasAndAliasesThrowsError() throws IOException { } b.endObject(); try (XContentParser parser = createParser(b)) { - Exception e = expectThrows(ParsingException.class, () -> AliasActions.PARSER.apply(parser, null)); + Exception e = expectThrows(XContentParseException.class, () -> AliasActions.PARSER.apply(parser, null)); assertThat(e.getCause().getCause(), instanceOf(IllegalArgumentException.class)); - assertEquals("Only one of [alias] and [aliases] is supported", e.getCause().getCause().getMessage()); + assertThat(e.getCause().getCause().getMessage(), containsString("Only one of [alias] and [aliases] is supported")); } } diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestTests.java index 16afa92fb0377..1e8d8e2a2932c 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestTests.java @@ -22,7 +22,6 @@ import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequestTests; -import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput; @@ -33,6 +32,7 @@ import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.common.xcontent.XContentParseException; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.RandomCreateIndexGenerator; import org.elasticsearch.indices.IndicesModule; @@ -172,7 +172,7 @@ public void testUnknownFields() throws IOException { } builder.endObject(); BytesReference mutated = XContentTestUtils.insertRandomFields(xContentType, BytesReference.bytes(builder), null, random()); - expectThrows(ParsingException.class, () -> request.fromXContent(createParser(xContentType.xContent(), mutated))); + expectThrows(XContentParseException.class, () -> request.fromXContent(createParser(xContentType.xContent(), mutated))); } public void testSameConditionCanOnlyBeAddedOnce() { diff --git a/server/src/test/java/org/elasticsearch/index/query/IdsQueryBuilderTests.java b/server/src/test/java/org/elasticsearch/index/query/IdsQueryBuilderTests.java index e440fc0277229..a3c3aa3627c80 100644 --- a/server/src/test/java/org/elasticsearch/index/query/IdsQueryBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/index/query/IdsQueryBuilderTests.java @@ -33,6 +33,7 @@ import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsString; public class IdsQueryBuilderTests extends AbstractQueryTestCase { @@ -94,7 +95,7 @@ public void testIllegalArguments() { public void testIdsQueryWithInvalidValues() throws Exception { String query = "{ \"ids\": { \"values\": [[1]] } }"; ParsingException e = expectThrows(ParsingException.class, () -> parseQuery(query)); - assertEquals("[ids] failed to parse field [values]", e.getMessage()); + assertThat(e.getMessage(), containsString("[ids] failed to parse field [values]")); } public void testFromJson() throws IOException { diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/DateRangeTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/DateRangeTests.java index acb6b0f0992e0..08ae503102e86 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/DateRangeTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/DateRangeTests.java @@ -19,7 +19,8 @@ package org.elasticsearch.search.aggregations.bucket; -import org.elasticsearch.common.ParsingException; +import org.elasticsearch.ExceptionsHelper; +import org.elasticsearch.common.xcontent.XContentParseException; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.search.aggregations.BaseAggregationTestCase; @@ -78,8 +79,9 @@ public void testParsingRangeStrict() throws IOException { "]\n" + "}"; XContentParser parser = createParser(JsonXContent.jsonXContent, rangeAggregation); - ParsingException ex = expectThrows(ParsingException.class, () -> DateRangeAggregationBuilder.parse("aggregationName", parser)); - assertThat(ex.getDetailedMessage(), containsString("badField")); + XContentParseException ex = expectThrows(XContentParseException.class, + () -> DateRangeAggregationBuilder.parse("aggregationName", parser)); + assertThat(ExceptionsHelper.detailedMessage(ex), containsString("badField")); } } diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/GeoDistanceRangeTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/GeoDistanceRangeTests.java index 9549c22019b63..fcdbc81c0c63e 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/GeoDistanceRangeTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/GeoDistanceRangeTests.java @@ -19,10 +19,11 @@ package org.elasticsearch.search.aggregations.bucket; -import org.elasticsearch.common.ParsingException; +import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.common.geo.GeoDistance; import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.unit.DistanceUnit; +import org.elasticsearch.common.xcontent.XContentParseException; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.search.aggregations.BaseAggregationTestCase; @@ -78,8 +79,9 @@ public void testParsingRangeStrict() throws IOException { "]\n" + "}"; XContentParser parser = createParser(JsonXContent.jsonXContent, rangeAggregation); - ParsingException ex = expectThrows(ParsingException.class, () -> GeoDistanceAggregationBuilder.parse("aggregationName", parser)); - assertThat(ex.getDetailedMessage(), containsString("badField")); + XContentParseException ex = expectThrows(XContentParseException.class, + () -> GeoDistanceAggregationBuilder.parse("aggregationName", parser)); + assertThat(ExceptionsHelper.detailedMessage(ex), containsString("badField")); } /** diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/RangeTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/RangeTests.java index b502645a24c81..2cf03b9609328 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/RangeTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/RangeTests.java @@ -19,7 +19,8 @@ package org.elasticsearch.search.aggregations.bucket; -import org.elasticsearch.common.ParsingException; +import org.elasticsearch.ExceptionsHelper; +import org.elasticsearch.common.xcontent.XContentParseException; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.search.aggregations.BaseAggregationTestCase; @@ -74,8 +75,9 @@ public void testParsingRangeStrict() throws IOException { "]\n" + "}"; XContentParser parser = createParser(JsonXContent.jsonXContent, rangeAggregation); - ParsingException ex = expectThrows(ParsingException.class, () -> RangeAggregationBuilder.parse("aggregationName", parser)); - assertThat(ex.getDetailedMessage(), containsString("badField")); + XContentParseException ex = expectThrows(XContentParseException.class, + () -> RangeAggregationBuilder.parse("aggregationName", parser)); + assertThat(ExceptionsHelper.detailedMessage(ex), containsString("badField")); } /** diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoHashGridParserTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoHashGridParserTests.java index 7f46cb9e551a8..e431bf19ff3de 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoHashGridParserTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoHashGridParserTests.java @@ -18,8 +18,9 @@ */ package org.elasticsearch.search.aggregations.bucket.geogrid; -import org.elasticsearch.common.ParsingException; +import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.common.unit.DistanceUnit; +import org.elasticsearch.common.xcontent.XContentParseException; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.test.ESTestCase; @@ -73,8 +74,9 @@ public void testParseInvalidUnitPrecision() throws Exception { "{\"field\":\"my_loc\", \"precision\": \"10kg\", \"size\": \"500\", \"shard_size\": \"550\"}"); XContentParser.Token token = stParser.nextToken(); assertSame(XContentParser.Token.START_OBJECT, token); - ParsingException ex = expectThrows(ParsingException.class, () -> GeoGridAggregationBuilder.parse("geohash_grid", stParser)); - assertEquals("[geohash_grid] failed to parse field [precision]", ex.getMessage()); + XContentParseException ex = expectThrows(XContentParseException.class, + () -> GeoGridAggregationBuilder.parse("geohash_grid", stParser)); + assertThat(ex.getMessage(), containsString("[geohash_grid] failed to parse field [precision]")); assertThat(ex.getCause(), instanceOf(NumberFormatException.class)); assertEquals("For input string: \"10kg\"", ex.getCause().getMessage()); } @@ -84,8 +86,9 @@ public void testParseDistanceUnitPrecisionTooSmall() throws Exception { "{\"field\":\"my_loc\", \"precision\": \"1cm\", \"size\": \"500\", \"shard_size\": \"550\"}"); XContentParser.Token token = stParser.nextToken(); assertSame(XContentParser.Token.START_OBJECT, token); - ParsingException ex = expectThrows(ParsingException.class, () -> GeoGridAggregationBuilder.parse("geohash_grid", stParser)); - assertEquals("[geohash_grid] failed to parse field [precision]", ex.getMessage()); + XContentParseException ex = expectThrows(XContentParseException.class, + () -> GeoGridAggregationBuilder.parse("geohash_grid", stParser)); + assertThat(ex.getMessage(), containsString("[geohash_grid] failed to parse field [precision]")); assertThat(ex.getCause(), instanceOf(IllegalArgumentException.class)); assertEquals("precision too high [1cm]", ex.getCause().getMessage()); } @@ -94,8 +97,10 @@ public void testParseErrorOnBooleanPrecision() throws Exception { XContentParser stParser = createParser(JsonXContent.jsonXContent, "{\"field\":\"my_loc\", \"precision\":false}"); XContentParser.Token token = stParser.nextToken(); assertSame(XContentParser.Token.START_OBJECT, token); - Exception e = expectThrows(ParsingException.class, () -> GeoGridAggregationBuilder.parse("geohash_grid", stParser)); - assertThat(e.getMessage(), containsString("[geohash_grid] precision doesn't support values of type: VALUE_BOOLEAN")); + XContentParseException e = expectThrows(XContentParseException.class, + () -> GeoGridAggregationBuilder.parse("geohash_grid", stParser)); + assertThat(ExceptionsHelper.detailedMessage(e), + containsString("[geohash_grid] precision doesn't support values of type: VALUE_BOOLEAN")); } public void testParseErrorOnPrecisionOutOfRange() throws Exception { @@ -105,9 +110,9 @@ public void testParseErrorOnPrecisionOutOfRange() throws Exception { try { GeoGridAggregationBuilder.parse("geohash_grid", stParser); fail(); - } catch (ParsingException ex) { + } catch (XContentParseException ex) { assertThat(ex.getCause(), instanceOf(IllegalArgumentException.class)); assertEquals("Invalid geohash aggregation precision of 13. Must be between 1 and 12.", ex.getCause().getMessage()); } } -} \ No newline at end of file +} diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/significant/SignificanceHeuristicTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/significant/SignificanceHeuristicTests.java index b8c9825d9b5a5..02909d673beb0 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/significant/SignificanceHeuristicTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/significant/SignificanceHeuristicTests.java @@ -31,6 +31,7 @@ import org.elasticsearch.common.xcontent.ParseFieldRegistry; 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.json.JsonXContent; import org.elasticsearch.index.Index; @@ -270,7 +271,7 @@ protected void checkParseException(ParseFieldRegistry { @Override @@ -85,12 +89,8 @@ public void testExceptionMultipleMethods() throws IOException { XContentParser parser = createParser(JsonXContent.jsonXContent, illegalAgg); assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken()); assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); - ParsingException e = expectThrows(ParsingException.class, + XContentParseException e = expectThrows(XContentParseException.class, () -> PercentilesAggregationBuilder.parse("myPercentiles", parser)); - assertEquals( - "ParsingException[[percentiles] failed to parse field [hdr]]; " - + "nested: IllegalStateException[Only one percentiles method should be declared.];; " - + "java.lang.IllegalStateException: Only one percentiles method should be declared.", - e.getDetailedMessage()); + assertThat(ExceptionsHelper.detailedMessage(e), containsString("[percentiles] failed to parse field [hdr]")); } } diff --git a/server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightBuilderTests.java b/server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightBuilderTests.java index c002d08e6f7a4..5d06fd4cd400b 100644 --- a/server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightBuilderTests.java @@ -31,6 +31,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; @@ -69,6 +70,7 @@ import static java.util.Collections.emptyList; import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; public class HighlightBuilderTests extends ESTestCase { @@ -163,15 +165,15 @@ public void testUnknownArrayNameExpection() throws IOException { } { - ParsingException e = expectParseThrows(ParsingException.class, "{\n" + + XContentParseException e = expectParseThrows(XContentParseException.class, "{\n" + " \"fields\" : {\n" + " \"body\" : {\n" + " \"bad_fieldname\" : [ \"field1\" , \"field2\" ]\n" + " }\n" + " }\n" + "}\n"); - assertEquals("[highlight] failed to parse field [fields]", e.getMessage()); - assertEquals("[fields] failed to parse field [body]", e.getCause().getMessage()); + 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()); } } @@ -193,15 +195,15 @@ public void testUnknownFieldnameExpection() throws IOException { } { - ParsingException e = expectParseThrows(ParsingException.class, "{\n" + + XContentParseException e = expectParseThrows(XContentParseException.class, "{\n" + " \"fields\" : {\n" + " \"body\" : {\n" + " \"bad_fieldname\" : \"value\"\n" + " }\n" + " }\n" + "}\n"); - assertEquals("[highlight] failed to parse field [fields]", e.getMessage()); - assertEquals("[fields] failed to parse field [body]", e.getCause().getMessage()); + 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()); } } @@ -218,49 +220,50 @@ public void testUnknownObjectFieldnameExpection() throws IOException { } { - ParsingException e = expectParseThrows(ParsingException.class, "{\n" + + XContentParseException e = expectParseThrows(XContentParseException.class, "{\n" + " \"fields\" : {\n" + " \"body\" : {\n" + " \"bad_fieldname\" : { \"field\" : \"value\" }\n" + " }\n" + " }\n" + "}\n"); - assertEquals("[highlight] failed to parse field [fields]", e.getMessage()); - assertEquals("[fields] failed to parse field [body]", e.getCause().getMessage()); + 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()); } } public void testStringInFieldsArray() throws IOException { - ParsingException e = expectParseThrows(ParsingException.class, "{\"fields\" : [ \"junk\" ]}"); - assertEquals("[highlight] failed to parse field [fields]", e.getMessage()); - assertEquals( - "[fields] can be a single object with any number of fields or an array where each entry is an object with a single field", - e.getCause().getMessage()); + XContentParseException e = expectParseThrows(XContentParseException.class, "{\"fields\" : [ \"junk\" ]}"); + assertThat(e.getMessage(), containsString("[highlight] failed to parse field [fields]")); + assertThat(e.getCause().getMessage(), + containsString("[fields] can be a single object with any number of fields " + + "or an array where each entry is an object with a single field")); } public void testNoFieldsInObjectInFieldsArray() throws IOException { - ParsingException e = expectParseThrows(ParsingException.class, "{\n" + + XContentParseException e = expectParseThrows(XContentParseException.class, "{\n" + " \"fields\" : [ {\n" + " }] \n" + "}\n"); - assertEquals("[highlight] failed to parse field [fields]", e.getMessage()); - assertEquals( - "[fields] can be a single object with any number of fields or an array where each entry is an object with a single field", - e.getCause().getMessage()); + assertThat(e.getMessage(), containsString("[highlight] failed to parse field [fields]")); + assertThat(e.getCause().getMessage(), + containsString("[fields] can be a single object with any number of fields " + + "or an array where each entry is an object with a single field")); } public void testTwoFieldsInObjectInFieldsArray() throws IOException { - ParsingException e = expectParseThrows(ParsingException.class, "{\n" + + XContentParseException e = expectParseThrows(XContentParseException.class, "{\n" + " \"fields\" : [ {\n" + " \"body\" : {},\n" + " \"nope\" : {}\n" + " }] \n" + "}\n"); - assertEquals("[highlight] failed to parse field [fields]", e.getMessage()); - assertEquals( - "[fields] can be a single object with any number of fields or an array where each entry is an object with a single field", - e.getCause().getMessage()); } + assertThat(e.getMessage(), containsString("[highlight] failed to parse field [fields]")); + assertThat(e.getCause().getMessage(), + containsString("[fields] can be a single object with any number of fields " + + "or an array where each entry is an object with a single field")); + } /** * test that build() outputs a {@link SearchContextHighlight} that is has similar parameters @@ -405,10 +408,10 @@ public void testParsingTagsSchema() throws IOException { assertArrayEquals("setting tags_schema 'default' should alter post_tags", HighlightBuilder.DEFAULT_POST_TAGS, highlightBuilder.postTags()); - ParsingException e = expectParseThrows(ParsingException.class, "{\n" + + XContentParseException e = expectParseThrows(XContentParseException.class, "{\n" + " \"tags_schema\" : \"somthing_else\"\n" + "}\n"); - assertEquals("[highlight] failed to parse field [tags_schema]", e.getMessage()); + assertThat(e.getMessage(), containsString("[highlight] failed to parse field [tags_schema]")); assertEquals("Unknown tag schema [somthing_else]", e.getCause().getMessage()); } @@ -436,20 +439,20 @@ public void testParsingEmptyStructure() throws IOException { } public void testPreTagsWithoutPostTags() throws IOException { - ParsingException e = expectParseThrows(ParsingException.class, "{\n" + + ParsingException err = expectParseThrows(ParsingException.class, "{\n" + " \"pre_tags\" : [\"\"]\n" + "}\n"); - assertEquals("pre_tags are set but post_tags are not set", e.getMessage()); + assertEquals("pre_tags are set but post_tags are not set", err.getMessage()); - e = expectParseThrows(ParsingException.class, "{\n" + + XContentParseException e = expectParseThrows(XContentParseException.class, "{\n" + " \"fields\" : {\n" + " \"body\" : {\n" + " \"pre_tags\" : [\"\"]\n" + " }\n" + " }\n" + "}\n"); - assertEquals("[highlight] failed to parse field [fields]", e.getMessage()); - assertEquals("[fields] failed to parse field [body]", e.getCause().getMessage()); + assertThat(e.getMessage(), containsString("[highlight] failed to parse field [fields]")); + assertThat(e.getCause().getMessage(), containsString("[fields] failed to parse field [body]")); assertEquals("pre_tags are set but post_tags are not set", e.getCause().getCause().getMessage()); } diff --git a/server/src/test/java/org/elasticsearch/search/rescore/QueryRescorerBuilderTests.java b/server/src/test/java/org/elasticsearch/search/rescore/QueryRescorerBuilderTests.java index 9a9797734b65f..75ac542d9853a 100644 --- a/server/src/test/java/org/elasticsearch/search/rescore/QueryRescorerBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/search/rescore/QueryRescorerBuilderTests.java @@ -31,6 +31,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; @@ -55,6 +56,7 @@ import static java.util.Collections.emptyList; import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode; +import static org.hamcrest.Matchers.containsString; public class QueryRescorerBuilderTests extends ESTestCase { @@ -262,8 +264,8 @@ public void testUnknownFieldsExpection() throws IOException { "}\n"; { XContentParser parser = createParser(rescoreElement); - Exception e = expectThrows(ParsingException.class, () -> RescorerBuilder.parseFromXContent(parser)); - assertEquals("[query] failed to parse field [rescore_query]", e.getMessage()); + Exception e = expectThrows(XContentParseException.class, () -> RescorerBuilder.parseFromXContent(parser)); + assertThat(e.getMessage(), containsString("[query] failed to parse field [rescore_query]")); } rescoreElement = "{\n" + diff --git a/server/src/test/java/org/elasticsearch/search/sort/ScriptSortBuilderTests.java b/server/src/test/java/org/elasticsearch/search/sort/ScriptSortBuilderTests.java index 9a28740d7271f..ed83011c26609 100644 --- a/server/src/test/java/org/elasticsearch/search/sort/ScriptSortBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/search/sort/ScriptSortBuilderTests.java @@ -25,6 +25,7 @@ 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; import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource; @@ -50,6 +51,7 @@ import java.util.Set; import static org.elasticsearch.search.sort.NestedSortBuilderTests.createRandomNestedSort; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.instanceOf; public class ScriptSortBuilderTests extends AbstractSortTestCase { @@ -246,8 +248,8 @@ public void testParseUnexpectedToken() throws IOException { parser.nextToken(); parser.nextToken(); - Exception e = expectThrows(ParsingException.class, () -> ScriptSortBuilder.fromXContent(parser, null)); - assertEquals("[_script] script doesn't support values of type: START_ARRAY", e.getMessage()); + Exception e = expectThrows(XContentParseException.class, () -> ScriptSortBuilder.fromXContent(parser, null)); + assertThat(e.getMessage(), containsString("[_script] script doesn't support values of type: START_ARRAY")); } /** diff --git a/server/src/test/java/org/elasticsearch/search/suggest/completion/CategoryContextMappingTests.java b/server/src/test/java/org/elasticsearch/search/suggest/completion/CategoryContextMappingTests.java index 9c62bb28483c1..b9da305e132f5 100644 --- a/server/src/test/java/org/elasticsearch/search/suggest/completion/CategoryContextMappingTests.java +++ b/server/src/test/java/org/elasticsearch/search/suggest/completion/CategoryContextMappingTests.java @@ -28,10 +28,12 @@ import org.apache.lucene.search.suggest.document.ContextSuggestField; import org.apache.lucene.util.BytesRef; import org.elasticsearch.ElasticsearchParseException; +import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.xcontent.XContentBuilder; +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; @@ -403,8 +405,8 @@ public void testNULLQueryContextParsingBasic() throws Exception { XContentParser parser = createParser(JsonXContent.jsonXContent, BytesReference.bytes(builder)); CategoryContextMapping mapping = ContextBuilder.category("cat").build(); - Exception e = expectThrows(ElasticsearchParseException.class, () -> mapping.parseQueryContext(parser)); - assertEquals("category context must be an object, string, number or boolean", e.getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, () -> mapping.parseQueryContext(parser)); + assertThat(ExceptionsHelper.detailedMessage(e), containsString("category context must be an object, string, number or boolean")); } public void testQueryContextParsingArray() throws Exception { @@ -460,8 +462,8 @@ public void testQueryContextParsingMixedTypeValuesArrayHavingNULL() throws Excep XContentParser parser = createParser(JsonXContent.jsonXContent, BytesReference.bytes(builder)); CategoryContextMapping mapping = ContextBuilder.category("cat").build(); - Exception e = expectThrows(ElasticsearchParseException.class, () -> mapping.parseQueryContext(parser)); - assertEquals("category context must be an object, string, number or boolean", e.getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, () -> mapping.parseQueryContext(parser)); + assertThat(ExceptionsHelper.detailedMessage(e), containsString("category context must be an object, string, number or boolean")); } public void testQueryContextParsingObject() throws Exception { @@ -518,8 +520,8 @@ public void testQueryContextParsingObjectHavingNULL() throws Exception { XContentParser parser = createParser(JsonXContent.jsonXContent, BytesReference.bytes(builder)); CategoryContextMapping mapping = ContextBuilder.category("cat").build(); - Exception e = expectThrows(ElasticsearchParseException.class, () -> mapping.parseQueryContext(parser)); - assertEquals("category context must be a string, number or boolean", e.getMessage()); + Exception e = expectThrows(XContentParseException.class, () -> mapping.parseQueryContext(parser)); + assertThat(e.getMessage(), containsString("category context must be a string, number or boolean")); } public void testQueryContextParsingObjectArray() throws Exception { @@ -619,8 +621,8 @@ public void testQueryContextParsingMixedTypeObjectArrayHavingNULL() throws Excep XContentParser parser = createParser(JsonXContent.jsonXContent, BytesReference.bytes(builder)); CategoryContextMapping mapping = ContextBuilder.category("cat").build(); - Exception e = expectThrows(ElasticsearchParseException.class, () -> mapping.parseQueryContext(parser)); - assertEquals("category context must be a string, number or boolean", e.getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, () -> mapping.parseQueryContext(parser)); + assertThat(ExceptionsHelper.detailedMessage(e), containsString("category context must be a string, number or boolean")); } @@ -676,8 +678,8 @@ public void testQueryContextParsingMixedHavingNULL() throws Exception { XContentParser parser = createParser(JsonXContent.jsonXContent, BytesReference.bytes(builder)); CategoryContextMapping mapping = ContextBuilder.category("cat").build(); - Exception e = expectThrows(ElasticsearchParseException.class, () -> mapping.parseQueryContext(parser)); - assertEquals("category context must be an object, string, number or boolean", e.getMessage()); + XContentParseException e = expectThrows(XContentParseException.class, () -> mapping.parseQueryContext(parser)); + assertThat(ExceptionsHelper.detailedMessage(e), containsString("category context must be an object, string, number or boolean")); } public void testUnknownQueryContextParsing() throws Exception { diff --git a/server/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java b/server/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java index 33b638286b4ae..ebfac5f58ef77 100644 --- a/server/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java +++ b/server/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java @@ -24,12 +24,12 @@ import org.apache.lucene.search.spell.LevensteinDistance; import org.apache.lucene.search.spell.LuceneLevenshteinDistance; import org.apache.lucene.search.spell.NGramDistance; -import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContent; 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; @@ -43,6 +43,7 @@ import java.util.function.Supplier; import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.core.IsInstanceOf.instanceOf; @@ -175,12 +176,12 @@ public void testIllegalXContent() throws IOException { // test bad value for field (e.g. size expects an int) directGenerator = "{ \"size\" : \"xxl\" }"; - assertIllegalXContent(directGenerator, ParsingException.class, + assertIllegalXContent(directGenerator, XContentParseException.class, "[direct_generator] failed to parse field [size]"); // test unexpected token directGenerator = "{ \"size\" : [ \"xxl\" ] }"; - assertIllegalXContent(directGenerator, ParsingException.class, + assertIllegalXContent(directGenerator, XContentParseException.class, "[direct_generator] size doesn't support values of type: START_ARRAY"); } @@ -188,7 +189,7 @@ private void assertIllegalXContent(String directGenerator, Class DirectCandidateGeneratorBuilder.PARSER.apply(parser, null)); - assertEquals(exceptionMsg, e.getMessage()); + assertThat(e.getMessage(), containsString(exceptionMsg)); } /** diff --git a/test/framework/src/main/java/org/elasticsearch/test/AbstractQueryTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/AbstractQueryTestCase.java index cc1e0d715af9a..1c02f960143ce 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/AbstractQueryTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/AbstractQueryTestCase.java @@ -60,6 +60,7 @@ import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentGenerator; 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; @@ -338,7 +339,7 @@ public final void testUnknownObjectException() throws IOException { if (expectedException) { fail("some parsing exception expected for query: " + testQuery); } - } catch (ParsingException | ElasticsearchParseException e) { + } catch (ParsingException | ElasticsearchParseException | XContentParseException e) { // different kinds of exception wordings depending on location // of mutation, so no simple asserts possible here if (expectedException == false) {