summaryrefslogtreecommitdiff
path: root/core/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java
diff options
context:
space:
mode:
authorLuca Cavanna <javanna@users.noreply.github.com>2017-01-24 16:12:45 +0100
committerGitHub <noreply@github.com>2017-01-24 16:12:45 +0100
commit47c0e13a3b0f4c64e0fa36c5706c0260a777d68b (patch)
treeead13f0fa584a522d9f21aa643b09a82b27326e7 /core/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java
parent12f53090417d01134f92281b8285a5783f971887 (diff)
Stop returning "es." internal exception headers as http response headers (#22703)
move "es." internal headers to separate metadata set in ElasticsearchException and stop returning them as response headers Closes #17593 * [TEST] remove ESExceptionTests, move its methods to ElasticsearchExceptionTests or ExceptionSerializationTests
Diffstat (limited to 'core/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java')
-rw-r--r--core/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java405
1 files changed, 337 insertions, 68 deletions
diff --git a/core/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java b/core/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java
index 576b53ad0e..4a8a90afab 100644
--- a/core/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java
+++ b/core/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java
@@ -21,73 +21,338 @@ package org.elasticsearch;
import org.apache.lucene.util.Constants;
import org.elasticsearch.action.RoutingMissingException;
+import org.elasticsearch.action.search.SearchPhaseExecutionException;
+import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.action.support.broadcast.BroadcastShardOperationFailedException;
import org.elasticsearch.cluster.block.ClusterBlockException;
+import org.elasticsearch.common.ParsingException;
+import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.bytes.BytesArray;
+import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentHelper;
+import org.elasticsearch.common.xcontent.XContentLocation;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.discovery.DiscoverySettings;
+import org.elasticsearch.index.Index;
+import org.elasticsearch.index.IndexNotFoundException;
+import org.elasticsearch.index.query.QueryShardException;
import org.elasticsearch.index.shard.IndexShardRecoveringException;
import org.elasticsearch.index.shard.ShardId;
+import org.elasticsearch.rest.RestStatus;
+import org.elasticsearch.search.SearchParseException;
+import org.elasticsearch.search.SearchShardTarget;
import org.elasticsearch.test.ESTestCase;
+import org.elasticsearch.test.TestSearchContext;
+import org.elasticsearch.transport.RemoteTransportException;
import org.hamcrest.Matcher;
+import java.io.EOFException;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collections;
import static java.util.Collections.singleton;
-import static org.hamcrest.CoreMatchers.equalTo;
+import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent;
import static org.hamcrest.CoreMatchers.hasItem;
-import static org.hamcrest.CoreMatchers.startsWith;
+import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.startsWith;
public class ElasticsearchExceptionTests extends ESTestCase {
+ public void testStatus() {
+ ElasticsearchException exception = new ElasticsearchException("test");
+ assertThat(exception.status(), equalTo(RestStatus.INTERNAL_SERVER_ERROR));
+
+ exception = new ElasticsearchException("test", new RuntimeException());
+ assertThat(exception.status(), equalTo(RestStatus.INTERNAL_SERVER_ERROR));
+
+ exception = new ElasticsearchException("test", new ResourceNotFoundException("test"));
+ assertThat(exception.status(), equalTo(RestStatus.INTERNAL_SERVER_ERROR));
+
+ exception = new RemoteTransportException("test", new ResourceNotFoundException("test"));
+ assertThat(exception.status(), equalTo(RestStatus.NOT_FOUND));
+
+ exception = new RemoteTransportException("test", new ResourceAlreadyExistsException("test"));
+ assertThat(exception.status(), equalTo(RestStatus.BAD_REQUEST));
+
+ exception = new RemoteTransportException("test", new IllegalArgumentException("foobar"));
+ assertThat(exception.status(), equalTo(RestStatus.BAD_REQUEST));
+
+ exception = new RemoteTransportException("test", new IllegalStateException("foobar"));
+ assertThat(exception.status(), equalTo(RestStatus.INTERNAL_SERVER_ERROR));
+ }
+
+ public void testGuessRootCause() {
+ {
+ ElasticsearchException exception = new ElasticsearchException("foo", new ElasticsearchException("bar",
+ new IndexNotFoundException("foo", new RuntimeException("foobar"))));
+ ElasticsearchException[] rootCauses = exception.guessRootCauses();
+ assertEquals(rootCauses.length, 1);
+ assertEquals(ElasticsearchException.getExceptionName(rootCauses[0]), "index_not_found_exception");
+ assertEquals(rootCauses[0].getMessage(), "no such index");
+ ShardSearchFailure failure = new ShardSearchFailure(new ParsingException(1, 2, "foobar", null),
+ new SearchShardTarget("node_1", new Index("foo", "_na_"), 1));
+ ShardSearchFailure failure1 = new ShardSearchFailure(new ParsingException(1, 2, "foobar", null),
+ new SearchShardTarget("node_1", new Index("foo", "_na_"), 2));
+ SearchPhaseExecutionException ex = new SearchPhaseExecutionException("search", "all shards failed",
+ new ShardSearchFailure[]{failure, failure1});
+ if (randomBoolean()) {
+ rootCauses = (randomBoolean() ? new RemoteTransportException("remoteboom", ex) : ex).guessRootCauses();
+ } else {
+ rootCauses = ElasticsearchException.guessRootCauses(randomBoolean() ? new RemoteTransportException("remoteboom", ex) : ex);
+ }
+ assertEquals(ElasticsearchException.getExceptionName(rootCauses[0]), "parsing_exception");
+ assertEquals(rootCauses[0].getMessage(), "foobar");
+
+ ElasticsearchException oneLevel = new ElasticsearchException("foo", new RuntimeException("foobar"));
+ rootCauses = oneLevel.guessRootCauses();
+ assertEquals(ElasticsearchException.getExceptionName(rootCauses[0]), "exception");
+ assertEquals(rootCauses[0].getMessage(), "foo");
+ }
+ {
+ ShardSearchFailure failure = new ShardSearchFailure(
+ new ParsingException(1, 2, "foobar", null),
+ new SearchShardTarget("node_1", new Index("foo", "_na_"), 1));
+ ShardSearchFailure failure1 = new ShardSearchFailure(new QueryShardException(new Index("foo1", "_na_"), "foobar", null),
+ new SearchShardTarget("node_1", new Index("foo1", "_na_"), 1));
+ ShardSearchFailure failure2 = new ShardSearchFailure(new QueryShardException(new Index("foo1", "_na_"), "foobar", null),
+ new SearchShardTarget("node_1", new Index("foo1", "_na_"), 2));
+ SearchPhaseExecutionException ex = new SearchPhaseExecutionException("search", "all shards failed",
+ new ShardSearchFailure[]{failure, failure1, failure2});
+ final ElasticsearchException[] rootCauses = ex.guessRootCauses();
+ assertEquals(rootCauses.length, 2);
+ assertEquals(ElasticsearchException.getExceptionName(rootCauses[0]), "parsing_exception");
+ assertEquals(rootCauses[0].getMessage(), "foobar");
+ assertEquals(((ParsingException) rootCauses[0]).getLineNumber(), 1);
+ assertEquals(((ParsingException) rootCauses[0]).getColumnNumber(), 2);
+ assertEquals(ElasticsearchException.getExceptionName(rootCauses[1]), "query_shard_exception");
+ assertEquals((rootCauses[1]).getIndex().getName(), "foo1");
+ assertEquals(rootCauses[1].getMessage(), "foobar");
+ }
+
+ {
+ final ElasticsearchException[] foobars = ElasticsearchException.guessRootCauses(new IllegalArgumentException("foobar"));
+ assertEquals(foobars.length, 1);
+ assertTrue(foobars[0] instanceof ElasticsearchException);
+ assertEquals(foobars[0].getMessage(), "foobar");
+ assertEquals(foobars[0].getCause().getClass(), IllegalArgumentException.class);
+ assertEquals(foobars[0].getExceptionName(), "illegal_argument_exception");
+ }
+ }
+
+ public void testDeduplicate() throws IOException {
+ {
+ ShardSearchFailure failure = new ShardSearchFailure(new ParsingException(1, 2, "foobar", null),
+ new SearchShardTarget("node_1", new Index("foo", "_na_"), 1));
+ ShardSearchFailure failure1 = new ShardSearchFailure(new ParsingException(1, 2, "foobar", null),
+ new SearchShardTarget("node_1", new Index("foo", "_na_"), 2));
+ SearchPhaseExecutionException ex = new SearchPhaseExecutionException("search", "all shards failed",
+ randomBoolean() ? failure1.getCause() : failure.getCause(), new ShardSearchFailure[]{failure, failure1});
+ XContentBuilder builder = XContentFactory.jsonBuilder();
+ builder.startObject();
+ ex.toXContent(builder, ToXContent.EMPTY_PARAMS);
+ builder.endObject();
+ String expected = "{\"type\":\"search_phase_execution_exception\",\"reason\":\"all shards failed\",\"phase\":\"search\"," +
+ "\"grouped\":true,\"failed_shards\":[{\"shard\":1,\"index\":\"foo\",\"node\":\"node_1\",\"reason\":" +
+ "{\"type\":\"parsing_exception\",\"reason\":\"foobar\",\"line\":1,\"col\":2}}]}";
+ assertEquals(expected, builder.string());
+ }
+ {
+ ShardSearchFailure failure = new ShardSearchFailure(new ParsingException(1, 2, "foobar", null),
+ new SearchShardTarget("node_1", new Index("foo", "_na_"), 1));
+ ShardSearchFailure failure1 = new ShardSearchFailure(new QueryShardException(new Index("foo1", "_na_"), "foobar", null),
+ new SearchShardTarget("node_1", new Index("foo1", "_na_"), 1));
+ ShardSearchFailure failure2 = new ShardSearchFailure(new QueryShardException(new Index("foo1", "_na_"), "foobar", null),
+ new SearchShardTarget("node_1", new Index("foo1", "_na_"), 2));
+ SearchPhaseExecutionException ex = new SearchPhaseExecutionException("search", "all shards failed",
+ new ShardSearchFailure[]{failure, failure1, failure2});
+ XContentBuilder builder = XContentFactory.jsonBuilder();
+ builder.startObject();
+ ex.toXContent(builder, ToXContent.EMPTY_PARAMS);
+ builder.endObject();
+ String expected = "{\"type\":\"search_phase_execution_exception\",\"reason\":\"all shards failed\"," +
+ "\"phase\":\"search\",\"grouped\":true,\"failed_shards\":[{\"shard\":1,\"index\":\"foo\",\"node\":\"node_1\"," +
+ "\"reason\":{\"type\":\"parsing_exception\",\"reason\":\"foobar\",\"line\":1,\"col\":2}},{\"shard\":1," +
+ "\"index\":\"foo1\",\"node\":\"node_1\",\"reason\":{\"type\":\"query_shard_exception\",\"reason\":\"foobar\"," +
+ "\"index_uuid\":\"_na_\",\"index\":\"foo1\"}}]}";
+ assertEquals(expected, builder.string());
+ }
+ {
+ ShardSearchFailure failure = new ShardSearchFailure(new ParsingException(1, 2, "foobar", null),
+ new SearchShardTarget("node_1", new Index("foo", "_na_"), 1));
+ ShardSearchFailure failure1 = new ShardSearchFailure(new ParsingException(1, 2, "foobar", null),
+ new SearchShardTarget("node_1", new Index("foo", "_na_"), 2));
+ NullPointerException nullPointerException = new NullPointerException();
+ SearchPhaseExecutionException ex = new SearchPhaseExecutionException("search", "all shards failed", nullPointerException,
+ new ShardSearchFailure[]{failure, failure1});
+ assertEquals(nullPointerException, ex.getCause());
+ XContentBuilder builder = XContentFactory.jsonBuilder();
+ builder.startObject();
+ ex.toXContent(builder, ToXContent.EMPTY_PARAMS);
+ builder.endObject();
+ String expected = "{\"type\":\"search_phase_execution_exception\",\"reason\":\"all shards failed\"," +
+ "\"phase\":\"search\",\"grouped\":true,\"failed_shards\":[{\"shard\":1,\"index\":\"foo\",\"node\":\"node_1\"," +
+ "\"reason\":{\"type\":\"parsing_exception\",\"reason\":\"foobar\",\"line\":1,\"col\":2}}]," +
+ "\"caused_by\":{\"type\":\"null_pointer_exception\",\"reason\":null}}";
+ assertEquals(expected, builder.string());
+ }
+ }
+
+ /**
+ * Check whether this exception contains an exception of the given type:
+ * either it is of the given class itself or it contains a nested cause
+ * of the given type.
+ *
+ * @param exType the exception type to look for
+ * @return whether there is a nested exception of the specified type
+ */
+ private static boolean contains(Throwable t, Class<? extends Throwable> exType) {
+ if (exType == null) {
+ return false;
+ }
+ for (Throwable cause = t; t != null; t = t.getCause()) {
+ if (exType.isInstance(cause)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void testGetRootCause() {
+ Exception root = new RuntimeException("foobar");
+ ElasticsearchException exception = new ElasticsearchException("foo", new ElasticsearchException("bar",
+ new IllegalArgumentException("index is closed", root)));
+ assertEquals(root, exception.getRootCause());
+ assertTrue(contains(exception, RuntimeException.class));
+ assertFalse(contains(exception, EOFException.class));
+ }
+
+ public void testToString() {
+ ElasticsearchException exception = new ElasticsearchException("foo", new ElasticsearchException("bar",
+ new IllegalArgumentException("index is closed", new RuntimeException("foobar"))));
+ assertEquals("ElasticsearchException[foo]; nested: ElasticsearchException[bar]; nested: IllegalArgumentException" +
+ "[index is closed]; nested: RuntimeException[foobar];", exception.toString());
+ }
+
public void testToXContent() throws IOException {
- ElasticsearchException e = new ElasticsearchException("test");
- assertExceptionAsJson(e, false, equalTo("{\"type\":\"exception\",\"reason\":\"test\"}"));
-
- e = new IndexShardRecoveringException(new ShardId("_test", "_0", 5));
- assertExceptionAsJson(e, false, equalTo("{\"type\":\"index_shard_recovering_exception\"," +
- "\"reason\":\"CurrentState[RECOVERING] Already recovering\",\"index_uuid\":\"_0\",\"shard\":\"5\",\"index\":\"_test\"}"));
-
- e = new BroadcastShardOperationFailedException(new ShardId("_index", "_uuid", 12), "foo", new IllegalStateException("bar"));
- assertExceptionAsJson(e, false, equalTo("{\"type\":\"illegal_state_exception\",\"reason\":\"bar\"}"));
-
- e = new ElasticsearchException(new IllegalArgumentException("foo"));
- assertExceptionAsJson(e, false, equalTo("{\"type\":\"exception\",\"reason\":\"java.lang.IllegalArgumentException: foo\"," +
- "\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"foo\"}}"));
-
- e = new ElasticsearchException("foo", new IllegalStateException("bar"));
- assertExceptionAsJson(e, false, equalTo("{\"type\":\"exception\",\"reason\":\"foo\"," +
- "\"caused_by\":{\"type\":\"illegal_state_exception\",\"reason\":\"bar\"}}"));
-
- // Test the same exception but with the "rest.exception.stacktrace.skip" parameter disabled: the stack_trace must be present
- // in the JSON. Since the stack can be large, it only checks the beginning of the JSON.
- assertExceptionAsJson(e, true, startsWith("{\"type\":\"exception\",\"reason\":\"foo\"," +
- "\"caused_by\":{\"type\":\"illegal_state_exception\",\"reason\":\"bar\"," +
- "\"stack_trace\":\"java.lang.IllegalStateException: bar" +
- (Constants.WINDOWS ? "\\r\\n" : "\\n") +
- "\\tat org.elasticsearch."));
+ {
+ ElasticsearchException e = new ElasticsearchException("test");
+ assertExceptionAsJson(e, "{\"type\":\"exception\",\"reason\":\"test\"}");
+ }
+ {
+ ElasticsearchException e = new IndexShardRecoveringException(new ShardId("_test", "_0", 5));
+ assertExceptionAsJson(e, "{\"type\":\"index_shard_recovering_exception\"," +
+ "\"reason\":\"CurrentState[RECOVERING] Already recovering\",\"index_uuid\":\"_0\"," +
+ "\"shard\":\"5\",\"index\":\"_test\"}");
+ }
+ {
+ ElasticsearchException e = new BroadcastShardOperationFailedException(new ShardId("_index", "_uuid", 12), "foo",
+ new IllegalStateException("bar"));
+ assertExceptionAsJson(e, "{\"type\":\"illegal_state_exception\",\"reason\":\"bar\"}");
+ }
+ {
+ ElasticsearchException e = new ElasticsearchException(new IllegalArgumentException("foo"));
+ assertExceptionAsJson(e, "{\"type\":\"exception\",\"reason\":\"java.lang.IllegalArgumentException: foo\"," +
+ "\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"foo\"}}");
+ }
+ {
+ ElasticsearchException e = new SearchParseException(new TestSearchContext(null), "foo", new XContentLocation(1,0));
+ assertExceptionAsJson(e, "{\"type\":\"search_parse_exception\",\"reason\":\"foo\",\"line\":1,\"col\":0}");
+ }
+ {
+ ElasticsearchException ex = new ElasticsearchException("foo",
+ new ElasticsearchException("bar", new IllegalArgumentException("index is closed", new RuntimeException("foobar"))));
+ assertExceptionAsJson(ex, "{\"type\":\"exception\",\"reason\":\"foo\",\"caused_by\":{\"type\":\"exception\"," +
+ "\"reason\":\"bar\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"index is closed\"," +
+ "\"caused_by\":{\"type\":\"runtime_exception\",\"reason\":\"foobar\"}}}}");
+ }
+ {
+ ElasticsearchException e = new ElasticsearchException("foo", new IllegalStateException("bar"));
+ assertExceptionAsJson(e, "{\"type\":\"exception\",\"reason\":\"foo\"," +
+ "\"caused_by\":{\"type\":\"illegal_state_exception\",\"reason\":\"bar\"}}");
+
+ // Test the same exception but with the "rest.exception.stacktrace.skip" parameter disabled: the stack_trace must be present
+ // in the JSON. Since the stack can be large, it only checks the beginning of the JSON.
+ ToXContent.Params params = new ToXContent.MapParams(
+ Collections.singletonMap(ElasticsearchException.REST_EXCEPTION_SKIP_STACK_TRACE, "false"));
+ String actual;
+ try (XContentBuilder builder = XContentBuilder.builder(XContentType.JSON.xContent())) {
+ builder.startObject();
+ e.toXContent(builder, params);
+ builder.endObject();
+ actual = builder.string();
+ }
+ assertThat(actual, startsWith("{\"type\":\"exception\",\"reason\":\"foo\"," +
+ "\"caused_by\":{\"type\":\"illegal_state_exception\",\"reason\":\"bar\"," +
+ "\"stack_trace\":\"java.lang.IllegalStateException: bar" +
+ (Constants.WINDOWS ? "\\r\\n" : "\\n") +
+ "\\tat org.elasticsearch."));
+ }
}
- public void testToXContentWithHeaders() throws IOException {
+ public void testGenerateThrowableToXContent() throws IOException {
+ {
+ Exception ex;
+ if (randomBoolean()) {
+ // just a wrapper which is omitted
+ ex = new RemoteTransportException("foobar", new FileNotFoundException("foo not found"));
+ } else {
+ ex = new FileNotFoundException("foo not found");
+ }
+ assertExceptionAsJson(ex, "{\"type\":\"file_not_found_exception\",\"reason\":\"foo not found\"}");
+ }
+ {
+ ParsingException ex = new ParsingException(1, 2, "foobar", null);
+ assertExceptionAsJson(ex, "{\"type\":\"parsing_exception\",\"reason\":\"foobar\",\"line\":1,\"col\":2}");
+ }
+
+ { // test equivalence
+ ElasticsearchException ex = new RemoteTransportException("foobar", new FileNotFoundException("foo not found"));
+ String toXContentString = Strings.toString(ex);
+ String throwableString = Strings.toString((builder, params) -> {
+ ElasticsearchException.generateThrowableXContent(builder, params, ex);
+ return builder;
+ });
+
+ assertEquals(throwableString, toXContentString);
+ assertEquals("{\"type\":\"file_not_found_exception\",\"reason\":\"foo not found\"}", toXContentString);
+ }
+
+ { // render header and metadata
+ ParsingException ex = new ParsingException(1, 2, "foobar", null);
+ ex.addMetadata("es.test1", "value1");
+ ex.addMetadata("es.test2", "value2");
+ ex.addHeader("test", "some value");
+ ex.addHeader("test_multi", "some value", "another value");
+ String expected = "{\"type\":\"parsing_exception\",\"reason\":\"foobar\",\"line\":1,\"col\":2," +
+ "\"test1\":\"value1\",\"test2\":\"value2\"," +
+ "\"header\":{\"test_multi\":" +
+ "[\"some value\",\"another value\"],\"test\":\"some value\"}}";
+ assertExceptionAsJson(ex, expected);
+ }
+ }
+
+ public void testToXContentWithHeadersAndMetadata() throws IOException {
ElasticsearchException e = new ElasticsearchException("foo",
new ElasticsearchException("bar",
new ElasticsearchException("baz",
new ClusterBlockException(singleton(DiscoverySettings.NO_MASTER_BLOCK_WRITES)))));
e.addHeader("foo_0", "0");
e.addHeader("foo_1", "1");
- e.addHeader("es.header_foo_0", "foo_0");
- e.addHeader("es.header_foo_1", "foo_1");
+ e.addMetadata("es.metadata_foo_0", "foo_0");
+ e.addMetadata("es.metadata_foo_1", "foo_1");
final String expectedJson = "{"
+ "\"type\":\"exception\","
+ "\"reason\":\"foo\","
- + "\"header_foo_0\":\"foo_0\","
- + "\"header_foo_1\":\"foo_1\","
+ + "\"metadata_foo_0\":\"foo_0\","
+ + "\"metadata_foo_1\":\"foo_1\","
+ "\"caused_by\":{"
+ "\"type\":\"exception\","
+ "\"reason\":\"bar\","
@@ -106,7 +371,7 @@ public class ElasticsearchExceptionTests extends ESTestCase {
+ "}"
+ "}";
- assertExceptionAsJson(e, false, equalTo(expectedJson));
+ assertExceptionAsJson(e, expectedJson);
ElasticsearchException parsed;
try (XContentParser parser = createParser(XContentType.JSON.xContent(), expectedJson)) {
@@ -118,11 +383,12 @@ public class ElasticsearchExceptionTests extends ESTestCase {
assertNotNull(parsed);
assertEquals(parsed.getMessage(), "Elasticsearch exception [type=exception, reason=foo]");
- assertThat(parsed.getHeaderKeys(), hasSize(4));
- assertEquals(parsed.getHeader("header_foo_0").get(0), "foo_0");
- assertEquals(parsed.getHeader("header_foo_1").get(0), "foo_1");
+ assertThat(parsed.getHeaderKeys(), hasSize(2));
assertEquals(parsed.getHeader("foo_0").get(0), "0");
assertEquals(parsed.getHeader("foo_1").get(0), "1");
+ assertThat(parsed.getMetadataKeys(), hasSize(2));
+ assertEquals(parsed.getMetadata("es.metadata_foo_0").get(0), "foo_0");
+ assertEquals(parsed.getMetadata("es.metadata_foo_1").get(0), "foo_1");
ElasticsearchException cause = (ElasticsearchException) parsed.getCause();
assertEquals(cause.getMessage(), "Elasticsearch exception [type=exception, reason=bar]");
@@ -185,24 +451,25 @@ public class ElasticsearchExceptionTests extends ESTestCase {
cause = (ElasticsearchException) cause.getCause();
assertEquals(cause.getMessage(),
"Elasticsearch exception [type=routing_missing_exception, reason=routing is required for [_test]/[_type]/[_id]]");
- assertThat(cause.getHeaderKeys(), hasSize(2));
- assertThat(cause.getHeader("index"), hasItem("_test"));
- assertThat(cause.getHeader("index_uuid"), hasItem("_na_"));
+ assertThat(cause.getHeaderKeys(), hasSize(0));
+ assertThat(cause.getMetadataKeys(), hasSize(2));
+ assertThat(cause.getMetadata("es.index"), hasItem("_test"));
+ assertThat(cause.getMetadata("es.index_uuid"), hasItem("_na_"));
}
- public void testFromXContentWithHeaders() throws IOException {
+ public void testFromXContentWithHeadersAndMetadata() throws IOException {
RoutingMissingException routing = new RoutingMissingException("_test", "_type", "_id");
ElasticsearchException baz = new ElasticsearchException("baz", routing);
baz.addHeader("baz_0", "baz0");
- baz.addHeader("es.baz_1", "baz1");
+ baz.addMetadata("es.baz_1", "baz1");
baz.addHeader("baz_2", "baz2");
- baz.addHeader("es.baz_3", "baz3");
+ baz.addMetadata("es.baz_3", "baz3");
ElasticsearchException bar = new ElasticsearchException("bar", baz);
- bar.addHeader("es.bar_0", "bar0");
+ bar.addMetadata("es.bar_0", "bar0");
bar.addHeader("bar_1", "bar1");
- bar.addHeader("es.bar_2", "bar2");
+ bar.addMetadata("es.bar_2", "bar2");
ElasticsearchException foo = new ElasticsearchException("foo", bar);
- foo.addHeader("es.foo_0", "foo0");
+ foo.addMetadata("es.foo_0", "foo0");
foo.addHeader("foo_1", "foo1");
final XContent xContent = randomFrom(XContentType.values()).xContent();
@@ -218,31 +485,35 @@ public class ElasticsearchExceptionTests extends ESTestCase {
assertNotNull(parsed);
assertEquals(parsed.getMessage(), "Elasticsearch exception [type=exception, reason=foo]");
- assertThat(parsed.getHeaderKeys(), hasSize(2));
- assertThat(parsed.getHeader("foo_0"), hasItem("foo0"));
+ assertThat(parsed.getHeaderKeys(), hasSize(1));
assertThat(parsed.getHeader("foo_1"), hasItem("foo1"));
+ assertThat(parsed.getMetadataKeys(), hasSize(1));
+ assertThat(parsed.getMetadata("es.foo_0"), hasItem("foo0"));
ElasticsearchException cause = (ElasticsearchException) parsed.getCause();
assertEquals(cause.getMessage(), "Elasticsearch exception [type=exception, reason=bar]");
- assertThat(cause.getHeaderKeys(), hasSize(3));
- assertThat(cause.getHeader("bar_0"), hasItem("bar0"));
+ assertThat(cause.getHeaderKeys(), hasSize(1));
assertThat(cause.getHeader("bar_1"), hasItem("bar1"));
- assertThat(cause.getHeader("bar_2"), hasItem("bar2"));
+ assertThat(cause.getMetadataKeys(), hasSize(2));
+ assertThat(cause.getMetadata("es.bar_0"), hasItem("bar0"));
+ assertThat(cause.getMetadata("es.bar_2"), hasItem("bar2"));
cause = (ElasticsearchException) cause.getCause();
assertEquals(cause.getMessage(), "Elasticsearch exception [type=exception, reason=baz]");
- assertThat(cause.getHeaderKeys(), hasSize(4));
+ assertThat(cause.getHeaderKeys(), hasSize(2));
assertThat(cause.getHeader("baz_0"), hasItem("baz0"));
- assertThat(cause.getHeader("baz_1"), hasItem("baz1"));
assertThat(cause.getHeader("baz_2"), hasItem("baz2"));
- assertThat(cause.getHeader("baz_3"), hasItem("baz3"));
+ assertThat(cause.getMetadataKeys(), hasSize(2));
+ assertThat(cause.getMetadata("es.baz_1"), hasItem("baz1"));
+ assertThat(cause.getMetadata("es.baz_3"), hasItem("baz3"));
cause = (ElasticsearchException) cause.getCause();
assertEquals(cause.getMessage(),
"Elasticsearch exception [type=routing_missing_exception, reason=routing is required for [_test]/[_type]/[_id]]");
- assertThat(cause.getHeaderKeys(), hasSize(2));
- assertThat(cause.getHeader("index"), hasItem("_test"));
- assertThat(cause.getHeader("index_uuid"), hasItem("_na_"));
+ assertThat(cause.getHeaderKeys(), hasSize(0));
+ assertThat(cause.getMetadataKeys(), hasSize(2));
+ assertThat(cause.getMetadata("es.index"), hasItem("_test"));
+ assertThat(cause.getMetadata("es.index_uuid"), hasItem("_na_"));
}
/**
@@ -251,17 +522,15 @@ public class ElasticsearchExceptionTests extends ESTestCase {
* By default, the stack trace of the exception is not rendered. The parameter `errorTrace` forces the stack trace to
* be rendered like the REST API does when the "error_trace" parameter is set to true.
*/
- private static void assertExceptionAsJson(ElasticsearchException e, boolean errorTrace, Matcher<String> expected)
- throws IOException {
- ToXContent.Params params = ToXContent.EMPTY_PARAMS;
- if (errorTrace) {
- params = new ToXContent.MapParams(Collections.singletonMap(ElasticsearchException.REST_EXCEPTION_SKIP_STACK_TRACE, "false"));
- }
- try (XContentBuilder builder = XContentBuilder.builder(XContentType.JSON.xContent())) {
- builder.startObject();
- e.toXContent(builder, params);
- builder.endObject();
- assertThat(builder.bytes().utf8ToString(), expected);
- }
+ private static void assertToXContentAsJson(ToXContent e, String expectedJson) throws IOException {
+ BytesReference actual = XContentHelper.toXContent(e, XContentType.JSON, randomBoolean());
+ assertToXContentEquivalent(new BytesArray(expectedJson), actual, XContentType.JSON);
+ }
+
+ private static void assertExceptionAsJson(Exception e, String expectedJson) throws IOException {
+ assertToXContentAsJson((builder, params) -> {
+ ElasticsearchException.generateThrowableXContent(builder, params, e);
+ return builder;
+ }, expectedJson);
}
}