Skip to content

Commit c924c0f

Browse files
committed
Only output sub failures if there are some
1 parent 9024e22 commit c924c0f

File tree

3 files changed

+105
-1
lines changed

3 files changed

+105
-1
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.elasticsearch.common.io.stream.StreamOutput;
2020
import org.elasticsearch.common.io.stream.Writeable;
2121
import org.elasticsearch.common.lucene.Lucene;
22+
import org.elasticsearch.common.util.CollectionUtils;
2223
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
2324
import org.elasticsearch.common.xcontent.ChunkedToXContentHelper;
2425
import org.elasticsearch.common.xcontent.ChunkedToXContentObject;
@@ -408,7 +409,9 @@ public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params params
408409
public Iterator<? extends ToXContent> innerToXContentChunked(ToXContent.Params params) {
409410
return Iterators.concat(
410411
ChunkedToXContentHelper.chunk(SearchResponse.this::headerToXContent),
411-
ChunkedToXContentHelper.array(SUBSIDIARY_FAILURES.getPreferredName(), Iterators.forArray(subsidiaryFailures)),
412+
CollectionUtils.isEmpty(subsidiaryFailures)
413+
? Collections.emptyIterator()
414+
: ChunkedToXContentHelper.array(SUBSIDIARY_FAILURES.getPreferredName(), Iterators.forArray(subsidiaryFailures)),
412415
Iterators.single(clusters),
413416
Iterators.concat(
414417
hits.toXContentChunked(params),

server/src/test/java/org/elasticsearch/action/search/SearchResponseMergerTests.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import static java.util.Collections.emptyMap;
6161
import static java.util.Collections.singletonList;
6262
import static org.elasticsearch.test.InternalAggregationTestCase.emptyReduceContextBuilder;
63+
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
6364
import static org.hamcrest.Matchers.containsInAnyOrder;
6465
import static org.hamcrest.Matchers.equalTo;
6566
import static org.hamcrest.Matchers.greaterThan;
@@ -135,6 +136,60 @@ public void testMergeTookInMillis() throws InterruptedException {
135136
}
136137
}
137138

139+
public void testMergeSubsidiaryFailures() throws InterruptedException {
140+
SearchTimeProvider searchTimeProvider = new SearchTimeProvider(0, 0, () -> 0);
141+
try (
142+
SearchResponseMerger merger = new SearchResponseMerger(
143+
0,
144+
0,
145+
SearchContext.TRACK_TOTAL_HITS_ACCURATE,
146+
searchTimeProvider,
147+
emptyReduceContextBuilder()
148+
)
149+
) {
150+
List<SubsidiaryFailure> allFailures = new ArrayList<>();
151+
152+
for (int i = 0; i < numResponses; i++) {
153+
int numFailures = randomIntBetween(0, 3);
154+
SubsidiaryFailure[] subsidiaryFailures = new SubsidiaryFailure[numFailures];
155+
for (int j = 0; j < numFailures; j++) {
156+
subsidiaryFailures[j] = new SubsidiaryFailure(randomAlphaOfLength(5), new IllegalArgumentException());
157+
}
158+
Collections.addAll(allFailures, subsidiaryFailures);
159+
SearchResponse searchResponse = new SearchResponse(
160+
SearchHits.EMPTY_WITH_TOTAL_HITS,
161+
null,
162+
null,
163+
false,
164+
null,
165+
null,
166+
1,
167+
null,
168+
1,
169+
1,
170+
0,
171+
100L,
172+
ShardSearchFailure.EMPTY_ARRAY,
173+
subsidiaryFailures,
174+
SearchResponse.Clusters.EMPTY
175+
);
176+
try {
177+
addResponse(merger, searchResponse);
178+
} finally {
179+
searchResponse.decRef();
180+
}
181+
}
182+
awaitResponsesAdded();
183+
assertEquals(numResponses, merger.numResponses());
184+
SearchResponse mergedResponse = merger.getMergedResponse(SearchResponse.Clusters.EMPTY);
185+
try {
186+
assertThat(mergedResponse.getSubsidiaryFailures(), arrayContainingInAnyOrder(allFailures.toArray()));
187+
} finally {
188+
mergedResponse.decRef();
189+
}
190+
}
191+
}
192+
138193
public void testMergeShardFailures() throws InterruptedException {
139194
SearchTimeProvider searchTimeProvider = new SearchTimeProvider(0, 0, () -> 0);
140195
try (

server/src/test/java/org/elasticsearch/action/search/SearchResponseTests.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,52 @@ public void testToXContent() throws IOException {
413413
response.decRef();
414414
}
415415
}
416+
{
417+
SearchResponse response = new SearchResponse(
418+
sHits,
419+
null,
420+
null,
421+
false,
422+
null,
423+
null,
424+
1,
425+
null,
426+
0,
427+
0,
428+
0,
429+
0,
430+
ShardSearchFailure.EMPTY_ARRAY,
431+
new SubsidiaryFailure[] { new SubsidiaryFailure("rescore", new IOException("io")) },
432+
SearchResponse.Clusters.EMPTY
433+
);
434+
try {
435+
String expectedString = XContentHelper.stripWhitespace("""
436+
{
437+
"took": 0,
438+
"timed_out": false,
439+
"_shards": {
440+
"total": 0,
441+
"successful": 0,
442+
"skipped": 0,
443+
"failed": 0
444+
},
445+
"subsidiaryFailures": [ { "phase": "rescore", "failure":
446+
{"type":"i_o_exception", "reason":"io"}
447+
} ],
448+
"hits": {
449+
"total": {
450+
"value": 100,
451+
"relation": "eq"
452+
},
453+
"max_score": 1.5,
454+
"hits": [ { "_id": "id1", "_score": 2.0 } ]
455+
}
456+
}""");
457+
assertEquals(expectedString, Strings.toString(response));
458+
} finally {
459+
response.decRef();
460+
}
461+
}
416462
{
417463
SearchResponse response = new SearchResponse(
418464
sHits,

0 commit comments

Comments
 (0)