From c4f3da2b9d6294a1871a87b3e489f9896b95f72e Mon Sep 17 00:00:00 2001 From: Alexander Reelsen Date: Tue, 10 Dec 2013 16:09:45 +0100 Subject: [PATCH] Preference only_node with unknown nodeId returns useful exception When the search preference is set to only node, but this node is not a data (or does not exist), we return a search exception, which indicates, that this is actually a server problem. However specifying a non-existing node id is a client problem and should return a more useful error message than {"error":"SearchPhaseExecutionException[Failed to execute phase [query_fetch], all shards failed]","status":503} --- .../routing/operation/plain/PlainOperationRouting.java | 10 +++++++++- .../search/preference/SearchPreferenceTests.java | 9 +++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/elasticsearch/cluster/routing/operation/plain/PlainOperationRouting.java b/src/main/java/org/elasticsearch/cluster/routing/operation/plain/PlainOperationRouting.java index 3b5376ae799..61f61cd7b0c 100644 --- a/src/main/java/org/elasticsearch/cluster/routing/operation/plain/PlainOperationRouting.java +++ b/src/main/java/org/elasticsearch/cluster/routing/operation/plain/PlainOperationRouting.java @@ -219,7 +219,9 @@ public class PlainOperationRouting extends AbstractComponent implements Operatio return indexShard.onlyNodeActiveInitializingShardsIt(localNodeId); } if (preference.startsWith("_only_node:")) { - return indexShard.onlyNodeActiveInitializingShardsIt(preference.substring("_only_node:".length())); + String nodeId = preference.substring("_only_node:".length()); + ensureNodeIdExists(nodes, nodeId); + return indexShard.onlyNodeActiveInitializingShardsIt(nodeId); } } // if not, then use it as the index @@ -284,4 +286,10 @@ public class PlainOperationRouting extends AbstractComponent implements Operatio } return hashFunction.hash(type, id); } + + private void ensureNodeIdExists(DiscoveryNodes nodes, String nodeId) { + if (!nodes.dataNodes().keys().contains(nodeId)) { + throw new ElasticSearchIllegalArgumentException("No data node with id[" + nodeId + "] found"); + } + } } diff --git a/src/test/java/org/elasticsearch/search/preference/SearchPreferenceTests.java b/src/test/java/org/elasticsearch/search/preference/SearchPreferenceTests.java index 870303dff7b..2a0448b8b3e 100644 --- a/src/test/java/org/elasticsearch/search/preference/SearchPreferenceTests.java +++ b/src/test/java/org/elasticsearch/search/preference/SearchPreferenceTests.java @@ -19,6 +19,7 @@ package org.elasticsearch.search.preference; +import org.elasticsearch.ElasticSearchIllegalArgumentException; import org.elasticsearch.action.admin.cluster.health.ClusterHealthStatus; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchType; @@ -96,4 +97,12 @@ public class SearchPreferenceTests extends ElasticsearchIntegrationTest { searchResponse = client().prepareSearch().setQuery(matchAllQuery()).setPreference("1234").execute().actionGet(); assertThat(searchResponse.getHits().totalHits(), equalTo(1l)); } + + @Test (expected = ElasticSearchIllegalArgumentException.class) + public void testThatSpecifyingNonExistingNodesReturnsUsefulError() throws Exception { + createIndex("test"); + ensureGreen(); + + client().prepareSearch().setQuery(matchAllQuery()).setPreference("_only_node:DOES-NOT-EXIST").execute().actionGet(); + } }