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}
This commit is contained in:
Alexander Reelsen 2013-12-10 16:09:45 +01:00
parent 7d3b78c293
commit c4f3da2b9d
2 changed files with 18 additions and 1 deletions

View File

@ -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");
}
}
}

View File

@ -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();
}
}