Skip to content

Commit db6f5a7

Browse files
committed
Search: When a search request failed completely (all shards fail) return a proper HTTP status code, closes #1035.
1 parent bbd73d5 commit db6f5a7

File tree

5 files changed

+58
-4
lines changed

5 files changed

+58
-4
lines changed

modules/elasticsearch/src/main/java/org/elasticsearch/action/search/SearchResponse.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.elasticsearch.common.xcontent.XContentBuilder;
2828
import org.elasticsearch.common.xcontent.XContentBuilderString;
2929
import org.elasticsearch.common.xcontent.XContentFactory;
30+
import org.elasticsearch.rest.RestStatus;
3031
import org.elasticsearch.search.SearchHits;
3132
import org.elasticsearch.search.facet.Facets;
3233
import org.elasticsearch.search.internal.InternalSearchResponse;
@@ -67,6 +68,24 @@ public SearchResponse(InternalSearchResponse internalResponse, String scrollId,
6768
this.shardFailures = shardFailures;
6869
}
6970

71+
public RestStatus status() {
72+
if (shardFailures.length == 0) {
73+
return RestStatus.OK;
74+
}
75+
if (successfulShards == 0 && totalShards > 0) {
76+
RestStatus status = shardFailures[0].status();
77+
if (shardFailures.length > 1) {
78+
for (int i = 1; i < shardFailures.length; i++) {
79+
if (shardFailures[i].status().getStatus() >= 500) {
80+
status = shardFailures[i].status();
81+
}
82+
}
83+
}
84+
return status;
85+
}
86+
return RestStatus.OK;
87+
}
88+
7089
/**
7190
* The search hits.
7291
*/
@@ -216,6 +235,7 @@ static final class Fields {
216235
static final XContentBuilderString SUCCESSFUL = new XContentBuilderString("successful");
217236
static final XContentBuilderString FAILED = new XContentBuilderString("failed");
218237
static final XContentBuilderString FAILURES = new XContentBuilderString("failures");
238+
static final XContentBuilderString STATUS = new XContentBuilderString("status");
219239
static final XContentBuilderString INDEX = new XContentBuilderString("index");
220240
static final XContentBuilderString SHARD = new XContentBuilderString("shard");
221241
static final XContentBuilderString REASON = new XContentBuilderString("reason");
@@ -242,6 +262,7 @@ static final class Fields {
242262
builder.field(Fields.INDEX, shardFailure.shard().index());
243263
builder.field(Fields.SHARD, shardFailure.shard().shardId());
244264
}
265+
builder.field(Fields.STATUS, shardFailure.status().getStatus());
245266
builder.field(Fields.REASON, shardFailure.reason());
246267
builder.endObject();
247268
}

modules/elasticsearch/src/main/java/org/elasticsearch/action/search/ShardSearchFailure.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@
1919

2020
package org.elasticsearch.action.search;
2121

22+
import org.elasticsearch.ElasticSearchException;
2223
import org.elasticsearch.ExceptionsHelper;
2324
import org.elasticsearch.action.ShardOperationFailedException;
2425
import org.elasticsearch.common.Nullable;
2526
import org.elasticsearch.common.io.stream.StreamInput;
2627
import org.elasticsearch.common.io.stream.StreamOutput;
28+
import org.elasticsearch.rest.RestStatus;
2729
import org.elasticsearch.search.SearchException;
2830
import org.elasticsearch.search.SearchShardTarget;
2931

@@ -44,6 +46,8 @@ public class ShardSearchFailure implements ShardOperationFailedException {
4446

4547
private String reason;
4648

49+
private RestStatus status;
50+
4751
private ShardSearchFailure() {
4852

4953
}
@@ -53,6 +57,11 @@ public ShardSearchFailure(Throwable t) {
5357
if (actual != null && actual instanceof SearchException) {
5458
this.shardTarget = ((SearchException) actual).shard();
5559
}
60+
if (actual != null && actual instanceof ElasticSearchException) {
61+
status = ((ElasticSearchException) t).status();
62+
} else {
63+
status = RestStatus.INTERNAL_SERVER_ERROR;
64+
}
5665
this.reason = ExceptionsHelper.detailedMessage(t);
5766
}
5867

@@ -62,12 +71,16 @@ public ShardSearchFailure(String reason, SearchShardTarget shardTarget) {
6271
}
6372

6473
/**
65-
* The search shard target the failure occured on.
74+
* The search shard target the failure occurred on.
6675
*/
6776
@Nullable public SearchShardTarget shard() {
6877
return this.shardTarget;
6978
}
7079

80+
public RestStatus status() {
81+
return this.status;
82+
}
83+
7184
/**
7285
* The index the search failed on.
7386
*/
@@ -110,6 +123,7 @@ public static ShardSearchFailure readShardSearchFailure(StreamInput in) throws I
110123
shardTarget = readSearchShardTarget(in);
111124
}
112125
reason = in.readUTF();
126+
status = RestStatus.readFrom(in);
113127
}
114128

115129
@Override public void writeTo(StreamOutput out) throws IOException {
@@ -120,5 +134,6 @@ public static ShardSearchFailure readShardSearchFailure(StreamInput in) throws I
120134
shardTarget.writeTo(out);
121135
}
122136
out.writeUTF(reason);
137+
RestStatus.writeTo(out, status);
123138
}
124139
}

modules/elasticsearch/src/main/java/org/elasticsearch/rest/RestStatus.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919

2020
package org.elasticsearch.rest;
2121

22+
import org.elasticsearch.common.io.stream.StreamInput;
23+
import org.elasticsearch.common.io.stream.StreamOutput;
24+
25+
import java.io.IOException;
26+
2227
public enum RestStatus {
2328
/**
2429
* The client SHOULD continue with its request. This interim response is used to inform the client that the
@@ -477,4 +482,12 @@ public enum RestStatus {
477482
public int getStatus() {
478483
return status;
479484
}
485+
486+
public static RestStatus readFrom(StreamInput in) throws IOException {
487+
return RestStatus.valueOf(in.readUTF());
488+
}
489+
490+
public static void writeTo(StreamOutput out, RestStatus status) throws IOException {
491+
out.writeUTF(status.name());
492+
}
480493
}

modules/elasticsearch/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public class RestSearchAction extends BaseRestHandler {
104104
builder.startObject();
105105
response.toXContent(builder, request);
106106
builder.endObject();
107-
channel.sendResponse(new XContentRestResponse(request, OK, builder));
107+
channel.sendResponse(new XContentRestResponse(request, response.status(), builder));
108108
} catch (Exception e) {
109109
if (logger.isDebugEnabled()) {
110110
logger.debug("failed to execute search (building response)", e);

modules/elasticsearch/src/main/java/org/elasticsearch/rest/action/search/RestSearchScrollAction.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@
2727
import org.elasticsearch.common.inject.Inject;
2828
import org.elasticsearch.common.settings.Settings;
2929
import org.elasticsearch.common.xcontent.XContentBuilder;
30-
import org.elasticsearch.rest.*;
30+
import org.elasticsearch.rest.BaseRestHandler;
31+
import org.elasticsearch.rest.RestChannel;
32+
import org.elasticsearch.rest.RestController;
33+
import org.elasticsearch.rest.RestRequest;
34+
import org.elasticsearch.rest.XContentRestResponse;
35+
import org.elasticsearch.rest.XContentThrowableRestResponse;
3136
import org.elasticsearch.search.Scroll;
3237

3338
import java.io.IOException;
@@ -86,7 +91,7 @@ public class RestSearchScrollAction extends BaseRestHandler {
8691
builder.startObject();
8792
response.toXContent(builder, request);
8893
builder.endObject();
89-
channel.sendResponse(new XContentRestResponse(request, OK, builder));
94+
channel.sendResponse(new XContentRestResponse(request, response.status(), builder));
9095
} catch (Exception e) {
9196
onFailure(e);
9297
}

0 commit comments

Comments
 (0)