From 8ac1b3c432a8f0ca89365cad37dfc4f21fe513c0 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Thu, 11 Sep 2025 07:28:12 -0700 Subject: [PATCH 1/2] Improve missing tranport version error message (#134506) This updates the error message to use a "more like this" algorithm to suggest transport versions that may exist but are misspelled. --- .../org/elasticsearch/TransportVersion.java | 23 +++++++++++++++++-- .../elasticsearch/TransportVersionTests.java | 21 +++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/TransportVersion.java b/server/src/main/java/org/elasticsearch/TransportVersion.java index 10641cae54e6d..4e0c28ea396fd 100644 --- a/server/src/main/java/org/elasticsearch/TransportVersion.java +++ b/server/src/main/java/org/elasticsearch/TransportVersion.java @@ -9,9 +9,11 @@ package org.elasticsearch; +import org.apache.lucene.search.spell.LevenshteinDistance; import org.elasticsearch.common.VersionId; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.core.Tuple; import org.elasticsearch.internal.VersionExtension; import org.elasticsearch.plugins.ExtensionLoader; @@ -234,12 +236,29 @@ public static TransportVersion fromId(int id) { * This will only return the latest known referable transport version for a given name and not its * patch versions. Patch versions are constructed as a linked list internally and may be found by * cycling through them in a loop using {@link TransportVersion#nextPatchVersion()}. - * */ public static TransportVersion fromName(String name) { TransportVersion known = VersionsHolder.ALL_VERSIONS_BY_NAME.get(name); if (known == null) { - throw new IllegalStateException("unknown transport version [" + name + "]"); + LevenshteinDistance ld = new LevenshteinDistance(); + List> scoredNames = new ArrayList<>(); + for (String key : VersionsHolder.ALL_VERSIONS_BY_NAME.keySet()) { + float distance = ld.getDistance(name, key); + if (distance > 0.7f) { + scoredNames.add(new Tuple<>(distance, key)); + } + } + StringBuilder message = new StringBuilder("Unknown transport version ["); + message.append(name); + message.append("]."); + if (scoredNames.isEmpty() == false) { + List names = scoredNames.stream().map(Tuple::v2).toList(); + message.append(" Did you mean "); + message.append(names); + message.append("?"); + } + message.append(" If this is a new transport version, run './gradle generateTransportVersion'."); + throw new IllegalStateException(message.toString()); } return known; } diff --git a/server/src/test/java/org/elasticsearch/TransportVersionTests.java b/server/src/test/java/org/elasticsearch/TransportVersionTests.java index a197c348c9c26..52972da50f0e3 100644 --- a/server/src/test/java/org/elasticsearch/TransportVersionTests.java +++ b/server/src/test/java/org/elasticsearch/TransportVersionTests.java @@ -400,4 +400,25 @@ public void testComment() { ); assertThat(new TransportVersion(null, 1000000, null).supports(test3), is(true)); } + + public void testMoreLikeThis() { + IllegalStateException ise = expectThrows(IllegalStateException.class, () -> TransportVersion.fromName("to_child_lock_join_query")); + assertThat( + ise.getMessage(), + is( + "Unknown transport version [to_child_lock_join_query]. " + + "Did you mean [to_child_block_join_query]? " + + "If this is a new transport version, run './gradle generateTransportVersion'." + ) + ); + + ise = expectThrows(IllegalStateException.class, () -> TransportVersion.fromName("brand_new_version_unrelated_to_others")); + assertThat( + ise.getMessage(), + is( + "Unknown transport version [brand_new_version_unrelated_to_others]. " + + "If this is a new transport version, run './gradle generateTransportVersion'." + ) + ); + } } From cfc10d2c40a9e1a1269c5a39080751bafc5e15ea Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Thu, 11 Sep 2025 09:32:20 -0700 Subject: [PATCH 2/2] fix tests --- .../org/elasticsearch/TransportVersionTests.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/TransportVersionTests.java b/server/src/test/java/org/elasticsearch/TransportVersionTests.java index 52972da50f0e3..73ec26b631fee 100644 --- a/server/src/test/java/org/elasticsearch/TransportVersionTests.java +++ b/server/src/test/java/org/elasticsearch/TransportVersionTests.java @@ -402,17 +402,10 @@ public void testComment() { } public void testMoreLikeThis() { - IllegalStateException ise = expectThrows(IllegalStateException.class, () -> TransportVersion.fromName("to_child_lock_join_query")); - assertThat( - ise.getMessage(), - is( - "Unknown transport version [to_child_lock_join_query]. " - + "Did you mean [to_child_block_join_query]? " - + "If this is a new transport version, run './gradle generateTransportVersion'." - ) + IllegalStateException ise = expectThrows( + IllegalStateException.class, + () -> TransportVersion.fromName("brand_new_version_unrelated_to_others") ); - - ise = expectThrows(IllegalStateException.class, () -> TransportVersion.fromName("brand_new_version_unrelated_to_others")); assertThat( ise.getMessage(), is(