diff --git a/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ErrorOnUnknown.java b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ErrorOnUnknown.java new file mode 100644 index 0000000000000..28ad02ff44812 --- /dev/null +++ b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ErrorOnUnknown.java @@ -0,0 +1,67 @@ +/* + * 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 java.util.ServiceLoader; + +/** + * Extension point to customize the error message for unknown fields. We expect + * Elasticsearch to plug a fancy implementation that uses Lucene's spelling + * correction infrastructure to suggest corrections. + */ +public interface ErrorOnUnknown { + /** + * The implementation of this interface that was loaded from SPI. + */ + ErrorOnUnknown IMPLEMENTATION = findImplementation(); + + /** + * Build the error message to use when {@link ObjectParser} encounters an unknown field. + * @param parserName the name of the thing we're parsing + * @param unknownField the field that we couldn't recognize + * @param candidates the possible fields + */ + String errorMessage(String parserName, String unknownField, Iterable candidates); + + /** + * Priority that this error message handler should be used. + */ + int priority(); + + private static ErrorOnUnknown findImplementation() { + ErrorOnUnknown best = new ErrorOnUnknown() { + @Override + public String errorMessage(String parserName, String unknownField, Iterable candidates) { + return "[" + parserName + "] unknown field [" + unknownField + "]"; + } + + @Override + public int priority() { + return Integer.MIN_VALUE; + } + }; + for (ErrorOnUnknown c : ServiceLoader.load(ErrorOnUnknown.class)) { + if (best.priority() < c.priority()) { + best = c; + } + } + return best; + } +} diff --git a/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ObjectParser.java b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ObjectParser.java index 69a4a4bd31e45..478b4c1369463 100644 --- a/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ObjectParser.java +++ b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ObjectParser.java @@ -81,18 +81,17 @@ public static BiConsumer> fromLi } private interface UnknownFieldParser { - - void acceptUnknownField(String parserName, String field, XContentLocation location, XContentParser parser, - Value value, Context context) throws IOException; + void acceptUnknownField(ObjectParser objectParser, String field, XContentLocation location, XContentParser parser, + Value value, Context context) throws IOException; } private static UnknownFieldParser ignoreUnknown() { - return (n, f, l, p, v, c) -> p.skipChildren(); + return (op, f, l, p, v, c) -> p.skipChildren(); } private static UnknownFieldParser errorOnUnknown() { - return (n, f, l, p, v, c) -> { - throw new XContentParseException(l, "[" + n + "] unknown field [" + f + "], parser not found"); + return (op, f, l, p, v, c) -> { + throw new XContentParseException(l, ErrorOnUnknown.IMPLEMENTATION.errorMessage(op.name, f, op.fieldParserMap.keySet())); }; } @@ -104,7 +103,7 @@ public interface UnknownFieldConsumer { } private static UnknownFieldParser consumeUnknownField(UnknownFieldConsumer consumer) { - return (parserName, field, location, parser, value, context) -> { + return (objectParser, field, location, parser, value, context) -> { XContentParser.Token t = parser.currentToken(); switch (t) { case VALUE_STRING: @@ -127,7 +126,7 @@ private static UnknownFieldParser consumeUnknow break; default: throw new XContentParseException(parser.getTokenLocation(), - "[" + parserName + "] cannot parse field [" + field + "] with value type [" + t + "]"); + "[" + objectParser.name + "] cannot parse field [" + field + "] with value type [" + t + "]"); } }; } @@ -136,12 +135,13 @@ private static UnknownFieldParser unk Class categoryClass, BiConsumer consumer ) { - return (parserName, field, location, parser, value, context) -> { + return (objectParser, field, location, parser, value, context) -> { Category o; try { o = parser.namedObject(categoryClass, field, context); } catch (NamedObjectNotFoundException e) { - throw new XContentParseException(location, "[" + parserName + "] " + e.getBareMessage(), e); + // TODO It'd be lovely if we could the options here but we don't have the right stuff plumbed through. We'll get to it! + throw new XContentParseException(location, "[" + objectParser.name + "] " + e.getBareMessage(), e); } consumer.accept(value, o); }; @@ -278,7 +278,7 @@ public Value parse(XContentParser parser, Value value, Context context) throws I throw new XContentParseException(parser.getTokenLocation(), "[" + name + "] no field found"); } if (fieldParser == null) { - unknownFieldParser.acceptUnknownField(name, currentFieldName, currentPosition, parser, value, context); + unknownFieldParser.acceptUnknownField(this, currentFieldName, currentPosition, parser, value, context); } else { fieldParser.assertSupports(name, parser, currentFieldName); parseSub(parser, fieldParser, currentFieldName, value, context); diff --git a/libs/x-content/src/test/java/org/elasticsearch/common/xcontent/ObjectParserTests.java b/libs/x-content/src/test/java/org/elasticsearch/common/xcontent/ObjectParserTests.java index 96d0f11af7c40..5b52d5b2e120d 100644 --- a/libs/x-content/src/test/java/org/elasticsearch/common/xcontent/ObjectParserTests.java +++ b/libs/x-content/src/test/java/org/elasticsearch/common/xcontent/ObjectParserTests.java @@ -206,7 +206,7 @@ public void setTest(int test) { { 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"); + assertEquals(ex.getMessage(), "[1:2] [the_parser] unknown field [not_supported_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 74683d8135ed7..a10459abfdce3 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 @@ -143,7 +143,6 @@ public void testXContentParsingIsNotLenient() throws IOException { exception = exception.getCause(); } assertThat(exception.getMessage(), containsString("unknown field")); - assertThat(exception.getMessage(), containsString("parser not found")); } } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/update/90_error.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/update/90_error.yml new file mode 100644 index 0000000000000..3102fd39afad9 --- /dev/null +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/update/90_error.yml @@ -0,0 +1,13 @@ +--- +'Misspelled fields get "did you mean"': + - skip: + version: " - 7.99.99" + reason: Implemented in 8.0 + - do: + catch: /\[UpdateRequest\] unknown field \[dac\] did you mean \[doc\]\?/ + update: + index: test + id: 1 + body: + dac: { foo: baz } + upsert: { foo: bar } diff --git a/server/src/main/java/org/elasticsearch/common/xcontent/SuggestingErrorOnUnknown.java b/server/src/main/java/org/elasticsearch/common/xcontent/SuggestingErrorOnUnknown.java new file mode 100644 index 0000000000000..c24f74ef814a7 --- /dev/null +++ b/server/src/main/java/org/elasticsearch/common/xcontent/SuggestingErrorOnUnknown.java @@ -0,0 +1,71 @@ +/* + * 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.apache.lucene.search.spell.LevenshteinDistance; +import org.apache.lucene.util.CollectionUtil; +import org.elasticsearch.common.collect.Tuple; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import static java.util.stream.Collectors.toList; + +public class SuggestingErrorOnUnknown implements ErrorOnUnknown { + @Override + public String errorMessage(String parserName, String unknownField, Iterable candidates) { + String message = String.format(Locale.ROOT, "[%s] unknown field [%s]", parserName, unknownField); + // TODO it'd be nice to combine this with BaseRestHandler's implementation. + LevenshteinDistance ld = new LevenshteinDistance(); + final List> scored = new ArrayList<>(); + for (String candidate : candidates) { + float distance = ld.getDistance(unknownField, candidate); + if (distance > 0.5f) { + scored.add(new Tuple<>(distance, candidate)); + } + } + if (scored.isEmpty()) { + return message; + } + CollectionUtil.timSort(scored, (a, b) -> { + // sort by distance in reverse order, then parameter name for equal distances + int compare = a.v1().compareTo(b.v1()); + if (compare != 0) { + return -compare; + } + return a.v2().compareTo(b.v2()); + }); + List keys = scored.stream().map(Tuple::v2).collect(toList()); + StringBuilder builder = new StringBuilder(message).append(" did you mean "); + if (keys.size() == 1) { + builder.append("[").append(keys.get(0)).append("]"); + } else { + builder.append("any of ").append(keys.toString()); + } + builder.append("?"); + return builder.toString(); + } + + @Override + public int priority() { + return 0; + } +} diff --git a/server/src/main/resources/META-INF/services/org.elasticsearch.common.xcontent.ErrorOnUnknown b/server/src/main/resources/META-INF/services/org.elasticsearch.common.xcontent.ErrorOnUnknown new file mode 100644 index 0000000000000..38f08271bce10 --- /dev/null +++ b/server/src/main/resources/META-INF/services/org.elasticsearch.common.xcontent.ErrorOnUnknown @@ -0,0 +1 @@ +org.elasticsearch.common.xcontent.SuggestingErrorOnUnknown diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/settings/ClusterUpdateSettingsRequestTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/settings/ClusterUpdateSettingsRequestTests.java index 06bd3dc26d8f6..5a581d2d4088e 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/settings/ClusterUpdateSettingsRequestTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/settings/ClusterUpdateSettingsRequestTests.java @@ -56,7 +56,7 @@ private void doFromXContentTestWithRandomFields(boolean addRandomFields) throws XContentParseException iae = expectThrows(XContentParseException.class, () -> ClusterUpdateSettingsRequest.fromXContent(createParser(xContentType.xContent(), mutated))); assertThat(iae.getMessage(), - containsString("[cluster_update_settings_request] unknown field [" + unsupportedField + "], parser not found")); + containsString("[cluster_update_settings_request] unknown field [" + unsupportedField + "]")); } else { try (XContentParser parser = createParser(xContentType.xContent(), originalBytes)) { ClusterUpdateSettingsRequest parsedRequest = ClusterUpdateSettingsRequest.fromXContent(parser); diff --git a/server/src/test/java/org/elasticsearch/action/update/UpdateRequestTests.java b/server/src/test/java/org/elasticsearch/action/update/UpdateRequestTests.java index 2d76256c91a85..20526366624fb 100644 --- a/server/src/test/java/org/elasticsearch/action/update/UpdateRequestTests.java +++ b/server/src/test/java/org/elasticsearch/action/update/UpdateRequestTests.java @@ -288,7 +288,7 @@ public void testUnknownFieldParsing() throws Exception { .endObject()); XContentParseException ex = expectThrows(XContentParseException.class, () -> request.fromXContent(contentParser)); - assertEquals("[1:2] [UpdateRequest] unknown field [unknown_field], parser not found", ex.getMessage()); + assertEquals("[1:2] [UpdateRequest] unknown field [unknown_field]", ex.getMessage()); UpdateRequest request2 = new UpdateRequest("test", "1"); XContentParser unknownObject = createParser(XContentFactory.jsonBuilder() @@ -299,7 +299,7 @@ public void testUnknownFieldParsing() throws Exception { .endObject() .endObject()); ex = expectThrows(XContentParseException.class, () -> request2.fromXContent(unknownObject)); - assertEquals("[1:76] [UpdateRequest] unknown field [params], parser not found", ex.getMessage()); + assertEquals("[1:76] [UpdateRequest] unknown field [params]", ex.getMessage()); } public void testFetchSourceParsing() throws Exception { diff --git a/server/src/test/java/org/elasticsearch/common/xcontent/SuggestingErrorOnUnknownTests.java b/server/src/test/java/org/elasticsearch/common/xcontent/SuggestingErrorOnUnknownTests.java new file mode 100644 index 0000000000000..8e2e0b05612a1 --- /dev/null +++ b/server/src/test/java/org/elasticsearch/common/xcontent/SuggestingErrorOnUnknownTests.java @@ -0,0 +1,46 @@ +/* + * 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.test.ESTestCase; + +import java.util.Arrays; + +import static org.hamcrest.Matchers.equalTo; + +public class SuggestingErrorOnUnknownTests extends ESTestCase { + private String errorMessage(String unknownField, String... candidates) { + return new SuggestingErrorOnUnknown().errorMessage("test", unknownField, Arrays.asList(candidates)); + } + + public void testNoCandidates() { + assertThat(errorMessage("foo"), equalTo("[test] unknown field [foo]")); + } + public void testBadCandidates() { + assertThat(errorMessage("foo", "bar", "baz"), equalTo("[test] unknown field [foo]")); + } + public void testOneCandidate() { + assertThat(errorMessage("foo", "bar", "fop"), equalTo("[test] unknown field [foo] did you mean [fop]?")); + } + public void testManyCandidate() { + assertThat(errorMessage("foo", "bar", "fop", "fou", "baz"), + equalTo("[test] unknown field [foo] did you mean any of [fop, fou]?")); + } +} 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 36c0d7ea12375..9a542fd762ad9 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 @@ -163,7 +163,7 @@ public void testUnknownArrayNameExpection() throws IOException { XContentParseException e = expectParseThrows(XContentParseException.class, "{\n" + " \"bad_fieldname\" : [ \"field1\" 1 \"field2\" ]\n" + "}\n"); - assertEquals("[2:5] [highlight] unknown field [bad_fieldname], parser not found", e.getMessage()); + assertEquals("[2:5] [highlight] unknown field [bad_fieldname]", e.getMessage()); } { @@ -176,7 +176,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("[4:9] [highlight_field] unknown field [bad_fieldname], parser not found", e.getCause().getCause().getMessage()); + assertEquals("[4:9] [highlight_field] unknown field [bad_fieldname]", e.getCause().getCause().getMessage()); } } @@ -194,7 +194,7 @@ public void testUnknownFieldnameExpection() throws IOException { XContentParseException e = expectParseThrows(XContentParseException.class, "{\n" + " \"bad_fieldname\" : \"value\"\n" + "}\n"); - assertEquals("[2:5] [highlight] unknown field [bad_fieldname], parser not found", e.getMessage()); + assertEquals("[2:5] [highlight] unknown field [bad_fieldname]", e.getMessage()); } { @@ -207,7 +207,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("[4:9] [highlight_field] unknown field [bad_fieldname], parser not found", e.getCause().getCause().getMessage()); + assertEquals("[4:9] [highlight_field] unknown field [bad_fieldname]", e.getCause().getCause().getMessage()); } } @@ -219,7 +219,7 @@ public void testUnknownObjectFieldnameExpection() throws IOException { XContentParseException e = expectParseThrows(XContentParseException.class, "{\n" + " \"bad_fieldname\" : { \"field\" : \"value\" }\n \n" + "}\n"); - assertEquals("[2:5] [highlight] unknown field [bad_fieldname], parser not found", e.getMessage()); + assertEquals("[2:5] [highlight] unknown field [bad_fieldname]", e.getMessage()); } { @@ -232,7 +232,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("[4:9] [highlight_field] unknown field [bad_fieldname], parser not found", e.getCause().getCause().getMessage()); + assertEquals("[4:9] [highlight_field] unknown field [bad_fieldname]", 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 302bffd668997..dfcc65afb5c65 100644 --- a/server/src/test/java/org/elasticsearch/search/rescore/QueryRescorerBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/search/rescore/QueryRescorerBuilderTests.java @@ -254,7 +254,7 @@ public void testUnknownFieldsExpection() throws IOException { "}\n"; try (XContentParser parser = createParser(rescoreElement)) { XContentParseException e = expectThrows(XContentParseException.class, () -> RescorerBuilder.parseFromXContent(parser)); - assertEquals("[3:17] [query] unknown field [bad_fieldname], parser not found", e.getMessage()); + assertEquals("[3:17] [query] unknown field [bad_fieldname]", e.getMessage()); } rescoreElement = "{\n" + diff --git a/server/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java b/server/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java index 750ec4f34dfa5..19351275f352c 100644 --- a/server/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java @@ -316,7 +316,7 @@ public void testUnknownOptionFails() throws IOException { parser.nextToken(); XContentParseException e = expectThrows(XContentParseException.class, () -> FieldSortBuilder.fromXContent(parser, "")); - assertEquals("[1:18] [field_sort] unknown field [reverse], parser not found", e.getMessage()); + assertEquals("[1:18] [field_sort] unknown field [reverse]", e.getMessage()); } } 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 2384d697e38dc..dbf78f6a4117d 100644 --- a/server/src/test/java/org/elasticsearch/search/sort/ScriptSortBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/search/sort/ScriptSortBuilderTests.java @@ -228,7 +228,7 @@ public void testParseBadFieldNameExceptions() throws IOException { parser.nextToken(); XContentParseException e = expectThrows(XContentParseException.class, () -> ScriptSortBuilder.fromXContent(parser, null)); - assertEquals("[1:15] [_script] unknown field [bad_field], parser not found", e.getMessage()); + assertEquals("[1:15] [_script] unknown field [bad_field]", e.getMessage()); } } @@ -241,7 +241,7 @@ public void testParseBadFieldNameExceptionsOnStartObject() throws IOException { parser.nextToken(); XContentParseException e = expectThrows(XContentParseException.class, () -> ScriptSortBuilder.fromXContent(parser, null)); - assertEquals("[1:15] [_script] unknown field [bad_field], parser not found", e.getMessage()); + assertEquals("[1:15] [_script] unknown field [bad_field]", e.getMessage()); } } 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 5bff24b934837..6b2d5b520f245 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 @@ -172,7 +172,7 @@ public void testIllegalXContent() throws IOException { // test unknown field directGenerator = "{ \"unknown_param\" : \"f1\" }"; assertIllegalXContent(directGenerator, IllegalArgumentException.class, - "[direct_generator] unknown field [unknown_param], parser not found"); + "[direct_generator] unknown field [unknown_param]"); // test bad value for field (e.g. size expects an int) directGenerator = "{ \"size\" : \"xxl\" }"; 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 2fd1bf450f51c..ba06640b41342 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/AbstractQueryTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/AbstractQueryTestCase.java @@ -189,7 +189,7 @@ public void testUnknownObjectException() throws IOException { if (expectedException == false) { throw new AssertionError("unexpected exception when parsing query:\n" + testQuery, e); } - assertThat(e.getMessage(), containsString("unknown field [newField], parser not found")); + assertThat(e.getMessage(), containsString("unknown field [newField]")); } } } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/datafeed/DatafeedConfigTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/datafeed/DatafeedConfigTests.java index 3d1677fcc78d3..4c8bd4168df20 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/datafeed/DatafeedConfigTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/datafeed/DatafeedConfigTests.java @@ -274,7 +274,7 @@ public void testFutureConfigParse() throws IOException { .createParser(xContentRegistry(), DeprecationHandler.THROW_UNSUPPORTED_OPERATION, FUTURE_DATAFEED); XContentParseException e = expectThrows(XContentParseException.class, () -> DatafeedConfig.STRICT_PARSER.apply(parser, null).build()); - assertEquals("[6:5] [datafeed_config] unknown field [tomorrows_technology_today], parser not found", e.getMessage()); + assertEquals("[6:5] [datafeed_config] unknown field [tomorrows_technology_today]", e.getMessage()); } public void testPastQueryConfigParse() throws IOException { diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/dataframe/DataFrameAnalyticsConfigTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/dataframe/DataFrameAnalyticsConfigTests.java index 428b63554d8cf..ad6f79fdd37ed 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/dataframe/DataFrameAnalyticsConfigTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/dataframe/DataFrameAnalyticsConfigTests.java @@ -328,7 +328,7 @@ public void testPreventCreateTimeInjection() throws IOException { XContentFactory.xContent(XContentType.JSON).createParser( xContentRegistry(), DeprecationHandler.THROW_UNSUPPORTED_OPERATION, json)) { Exception e = expectThrows(IllegalArgumentException.class, () -> DataFrameAnalyticsConfig.STRICT_PARSER.apply(parser, null)); - assertThat(e.getMessage(), containsString("unknown field [create_time], parser not found")); + assertThat(e.getMessage(), containsString("unknown field [create_time]")); } } @@ -343,7 +343,7 @@ public void testPreventVersionInjection() throws IOException { XContentFactory.xContent(XContentType.JSON).createParser( xContentRegistry(), DeprecationHandler.THROW_UNSUPPORTED_OPERATION, json)) { Exception e = expectThrows(IllegalArgumentException.class, () -> DataFrameAnalyticsConfig.STRICT_PARSER.apply(parser, null)); - assertThat(e.getMessage(), containsString("unknown field [version], parser not found")); + assertThat(e.getMessage(), containsString("unknown field [version]")); } } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/job/config/JobTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/job/config/JobTests.java index f8fea739a2500..0ca0e1ccd814b 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/job/config/JobTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/job/config/JobTests.java @@ -81,7 +81,7 @@ public void testFutureConfigParse() throws IOException { .createParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, FUTURE_JOB); XContentParseException e = expectThrows(XContentParseException.class, () -> Job.STRICT_PARSER.apply(parser, null).build()); - assertEquals("[4:5] [job_details] unknown field [tomorrows_technology_today], parser not found", e.getMessage()); + assertEquals("[4:5] [job_details] unknown field [tomorrows_technology_today]", e.getMessage()); } public void testFutureMetadataParse() throws IOException { diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/process/ProcessResultsParserTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/process/ProcessResultsParserTests.java index dff432ab938d9..77428c2304961 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/process/ProcessResultsParserTests.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/process/ProcessResultsParserTests.java @@ -41,7 +41,7 @@ public void testParse_GivenUnknownObject() throws IOException { XContentParseException e = expectThrows(XContentParseException.class, () -> parser.parseResults(inputStream).forEachRemaining(a -> { })); - assertEquals("[1:3] [test_result] unknown field [unknown], parser not found", e.getMessage()); + assertEquals("[1:3] [test_result] unknown field [unknown]", e.getMessage()); } } diff --git a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlTestCase.java b/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlTestCase.java index 3215c6b35efdf..d4cb83485d1e1 100644 --- a/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlTestCase.java +++ b/x-pack/plugin/sql/qa/src/main/java/org/elasticsearch/xpack/sql/qa/rest/RestSqlTestCase.java @@ -350,7 +350,7 @@ public void testUseColumnarForTranslateRequest() throws IOException { expectBadRequest(() -> { client().performRequest(request); return Collections.emptyMap(); - }, containsString("unknown field [columnar], parser not found")); + }, containsString("unknown field [columnar]")); } public static void expectBadRequest(CheckedSupplier, Exception> code, Matcher errorMessageMatcher) { diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/test/ml/data_frame_analytics_crud.yml b/x-pack/plugin/src/test/resources/rest-api-spec/test/ml/data_frame_analytics_crud.yml index 6dc8c800bd414..903ac36d90990 100644 --- a/x-pack/plugin/src/test/resources/rest-api-spec/test/ml/data_frame_analytics_crud.yml +++ b/x-pack/plugin/src/test/resources/rest-api-spec/test/ml/data_frame_analytics_crud.yml @@ -87,7 +87,7 @@ setup: --- "Test put config with security headers in the body": - do: - catch: /unknown field \[headers\], parser not found/ + catch: /unknown field \[headers\]/ ml.put_data_frame_analytics: id: "data_frame_with_header" body: > @@ -107,7 +107,7 @@ setup: "Test put config with create_time in the body": - do: - catch: /unknown field \[create_time\], parser not found/ + catch: /unknown field \[create_time\]/ ml.put_data_frame_analytics: id: "data_frame_with_create_time" body: > @@ -126,7 +126,7 @@ setup: "Test put config with version in the body": - do: - catch: /unknown field \[version\], parser not found/ + catch: /unknown field \[version\]/ ml.put_data_frame_analytics: id: "data_frame_with_version" body: > @@ -443,7 +443,7 @@ setup: "Test put config with unknown top level field": - do: - catch: /unknown field \[unknown_field\], parser not found/ + catch: /unknown field \[unknown_field\]/ ml.put_data_frame_analytics: id: "unknown_field" body: > diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/test/ml/datafeeds_crud.yml b/x-pack/plugin/src/test/resources/rest-api-spec/test/ml/datafeeds_crud.yml index 8c6e94635f4da..c63aa4b4e48d4 100644 --- a/x-pack/plugin/src/test/resources/rest-api-spec/test/ml/datafeeds_crud.yml +++ b/x-pack/plugin/src/test/resources/rest-api-spec/test/ml/datafeeds_crud.yml @@ -86,7 +86,7 @@ setup: --- "Test put datafeed with security headers in the body": - do: - catch: /unknown field \[headers\], parser not found/ + catch: /unknown field \[headers\]/ ml.put_datafeed: datafeed_id: test-datafeed-1 body: > diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/test/rollup/put_job.yml b/x-pack/plugin/src/test/resources/rest-api-spec/test/rollup/put_job.yml index 27b637ba7081d..530bf6414bbed 100644 --- a/x-pack/plugin/src/test/resources/rest-api-spec/test/rollup/put_job.yml +++ b/x-pack/plugin/src/test/resources/rest-api-spec/test/rollup/put_job.yml @@ -170,7 +170,7 @@ setup: "Try to include headers": - do: - catch: /unknown field \[headers\], parser not found/ + catch: /unknown field \[headers\]/ headers: Authorization: "Basic eF9wYWNrX3Jlc3RfdXNlcjp4LXBhY2stdGVzdC1wYXNzd29yZA==" # run as x_pack_rest_user, i.e. the test setup superuser rollup.put_job: diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/common/text/TextTemplateTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/common/text/TextTemplateTests.java index ecc071d598105..2ebaccc61801c 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/common/text/TextTemplateTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/common/text/TextTemplateTests.java @@ -196,7 +196,7 @@ public void testParserInvalidUnexpectedField() throws Exception { TextTemplate.parse(parser); fail("expected parse exception when encountering an unknown field"); } catch (IllegalArgumentException e) { - assertThat(e.getMessage(), containsString("[script] unknown field [unknown_field], parser not found")); + assertThat(e.getMessage(), containsString("[script] unknown field [unknown_field]")); } } @@ -210,7 +210,7 @@ public void testParserInvalidUnknownScriptType() throws Exception { XContentParser parser = createParser(JsonXContent.jsonXContent, bytes); parser.nextToken(); XContentParseException ex = expectThrows(XContentParseException.class, () -> TextTemplate.parse(parser)); - assertEquals("[1:2] [script] unknown field [template], parser not found", ex.getMessage()); + assertEquals("[1:2] [script] unknown field [template]", ex.getMessage()); } public void testParserInvalidMissingText() throws Exception { @@ -222,7 +222,7 @@ public void testParserInvalidMissingText() throws Exception { XContentParser parser = createParser(JsonXContent.jsonXContent, bytes); parser.nextToken(); XContentParseException ex = expectThrows(XContentParseException.class, () -> TextTemplate.parse(parser)); - assertEquals("[1:2] [script] unknown field [type], parser not found", ex.getMessage()); + assertEquals("[1:2] [script] unknown field [type]", ex.getMessage()); } public void testNullObject() throws Exception {