Skip to content

Commit a869342

Browse files
committed
Restore DefaultShardOperationFailedException's reason after deserialization (#45203)
The reason field of DefaultShardOperationFailedException is lost during serialization. This is sad because this field is checked for nullity during xcontent generation and it means that the cause won't be included in the generated xcontent and won't be printed in two REST API responses (Close Index API and Indices Shard Stores API). This commit simply restores the reason from the cause during deserialization.
1 parent bd59ee6 commit a869342

File tree

3 files changed

+71
-0
lines changed

3 files changed

+71
-0
lines changed

server/src/main/java/org/elasticsearch/action/support/DefaultShardOperationFailedException.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ public static void readFrom(StreamInput in, DefaultShardOperationFailedException
7979
f.shardId = in.readVInt();
8080
f.cause = in.readException();
8181
f.status = RestStatus.readFrom(in);
82+
f.reason = detailedMessage(f.cause);
8283
}
8384

8485
@Override

server/src/test/java/org/elasticsearch/action/admin/indices/close/CloseIndexResponseTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ protected void assertEqualInstances(CloseIndexResponse expected, CloseIndexRespo
113113
assertThat(actualFailure.getNodeId(), equalTo(expectedFailure.getNodeId()));
114114
assertThat(actualFailure.index(), equalTo(expectedFailure.index()));
115115
assertThat(actualFailure.shardId(), equalTo(expectedFailure.shardId()));
116+
assertThat(actualFailure.reason(), equalTo(expectedFailure.reason()));
116117
assertThat(actualFailure.getCause().getMessage(), equalTo(expectedFailure.getCause().getMessage()));
117118
assertThat(actualFailure.getCause().getClass(), equalTo(expectedFailure.getCause().getClass()));
118119
assertArrayEquals(actualFailure.getCause().getStackTrace(), expectedFailure.getCause().getStackTrace());

server/src/test/java/org/elasticsearch/action/support/DefaultShardOperationFailedExceptionTests.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,18 @@
1919

2020
package org.elasticsearch.action.support;
2121

22+
import org.apache.lucene.index.CorruptIndexException;
23+
import org.apache.lucene.index.IndexFormatTooNewException;
24+
import org.apache.lucene.index.IndexFormatTooOldException;
25+
import org.apache.lucene.store.AlreadyClosedException;
26+
import org.apache.lucene.store.LockObtainFailedException;
2227
import org.elasticsearch.ElasticsearchException;
2328
import org.elasticsearch.action.support.broadcast.BroadcastShardOperationFailedException;
2429
import org.elasticsearch.common.Strings;
2530
import org.elasticsearch.common.bytes.BytesReference;
31+
import org.elasticsearch.common.io.stream.BytesStreamOutput;
32+
import org.elasticsearch.common.io.stream.StreamInput;
33+
import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException;
2634
import org.elasticsearch.common.xcontent.XContent;
2735
import org.elasticsearch.common.xcontent.XContentBuilder;
2836
import org.elasticsearch.common.xcontent.XContentParser;
@@ -32,7 +40,12 @@
3240
import org.elasticsearch.rest.RestStatus;
3341
import org.elasticsearch.test.ESTestCase;
3442

43+
import java.io.EOFException;
44+
import java.io.FileNotFoundException;
3545
import java.io.IOException;
46+
import java.util.function.Supplier;
47+
48+
import static org.hamcrest.Matchers.equalTo;
3649

3750
public class DefaultShardOperationFailedExceptionTests extends ESTestCase {
3851

@@ -110,4 +123,60 @@ public void testFromXContent() throws IOException {
110123
assertEquals(parsed.status(), RestStatus.INTERNAL_SERVER_ERROR);
111124
assertEquals(parsed.getCause().getMessage(), "Elasticsearch exception [type=exception, reason=foo]");
112125
}
126+
127+
public void testSerialization() throws Exception {
128+
final DefaultShardOperationFailedException exception = randomInstance();
129+
try (BytesStreamOutput out = new BytesStreamOutput()) {
130+
exception.writeTo(out);
131+
132+
try (StreamInput in = out.bytes().streamInput()) {
133+
final DefaultShardOperationFailedException deserializedException = new DefaultShardOperationFailedException(in);
134+
assertNotSame(exception, deserializedException);
135+
assertThat(deserializedException.index(), equalTo(exception.index()));
136+
assertThat(deserializedException.shardId(), equalTo(exception.shardId()));
137+
assertThat(deserializedException.reason(), equalTo(exception.reason()));
138+
assertThat(deserializedException.getCause().getMessage(), equalTo(exception.getCause().getMessage()));
139+
assertThat(deserializedException.getCause().getClass(), equalTo(exception.getCause().getClass()));
140+
assertArrayEquals(deserializedException.getCause().getStackTrace(), exception.getCause().getStackTrace());
141+
}
142+
}
143+
}
144+
145+
private static DefaultShardOperationFailedException randomInstance() {
146+
final Exception cause = randomException();
147+
if (cause instanceof ElasticsearchException) {
148+
return new DefaultShardOperationFailedException((ElasticsearchException) cause);
149+
} else {
150+
return new DefaultShardOperationFailedException(randomAlphaOfLengthBetween(1, 5), randomIntBetween(0, 10), cause);
151+
}
152+
}
153+
154+
@SuppressWarnings("unchecked")
155+
private static Exception randomException() {
156+
Supplier<Exception> supplier = randomFrom(
157+
() -> new CorruptIndexException(randomAlphaOfLengthBetween(1, 5), randomAlphaOfLengthBetween(1, 5), randomExceptionOrNull()),
158+
() -> new NullPointerException(randomAlphaOfLengthBetween(1, 5)),
159+
() -> new NumberFormatException(randomAlphaOfLengthBetween(1, 5)),
160+
() -> new IllegalArgumentException(randomAlphaOfLengthBetween(1, 5), randomExceptionOrNull()),
161+
() -> new AlreadyClosedException(randomAlphaOfLengthBetween(1, 5), randomExceptionOrNull()),
162+
() -> new EOFException(randomAlphaOfLengthBetween(1, 5)),
163+
() -> new SecurityException(randomAlphaOfLengthBetween(1, 5), randomExceptionOrNull()),
164+
() -> new StringIndexOutOfBoundsException(randomAlphaOfLengthBetween(1, 5)),
165+
() -> new ArrayIndexOutOfBoundsException(randomAlphaOfLengthBetween(1, 5)),
166+
() -> new StringIndexOutOfBoundsException(randomAlphaOfLengthBetween(1, 5)),
167+
() -> new FileNotFoundException(randomAlphaOfLengthBetween(1, 5)),
168+
() -> new IllegalStateException(randomAlphaOfLengthBetween(1, 5), randomExceptionOrNull()),
169+
() -> new LockObtainFailedException(randomAlphaOfLengthBetween(1, 5), randomExceptionOrNull()),
170+
() -> new InterruptedException(randomAlphaOfLengthBetween(1, 5)),
171+
() -> new IOException(randomAlphaOfLengthBetween(1, 5), randomExceptionOrNull()),
172+
() -> new EsRejectedExecutionException(randomAlphaOfLengthBetween(1, 5), randomBoolean()),
173+
() -> new IndexFormatTooNewException(randomAlphaOfLengthBetween(1, 10), randomInt(), randomInt(), randomInt()),
174+
() -> new IndexFormatTooOldException(randomAlphaOfLengthBetween(1, 5), randomAlphaOfLengthBetween(1, 5))
175+
);
176+
return supplier.get();
177+
}
178+
179+
private static Exception randomExceptionOrNull() {
180+
return randomBoolean() ? randomException() : null;
181+
}
113182
}

0 commit comments

Comments
 (0)