Render strucutred exception in multi search
MultiMatch still only returns the exception message but should return the actual exception and render it in a structured fashion
This commit is contained in:
parent
0ce18954a0
commit
dc67bd0021
|
@ -20,6 +20,7 @@
|
|||
package org.elasticsearch.action.search;
|
||||
|
||||
import com.google.common.collect.Iterators;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
|
@ -31,6 +32,7 @@ import org.elasticsearch.common.xcontent.XContentBuilderString;
|
|||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
|
@ -43,22 +45,22 @@ public class MultiSearchResponse extends ActionResponse implements Iterable<Mult
|
|||
*/
|
||||
public static class Item implements Streamable {
|
||||
private SearchResponse response;
|
||||
private String failureMessage;
|
||||
private Throwable throwable;
|
||||
|
||||
Item() {
|
||||
|
||||
}
|
||||
|
||||
public Item(SearchResponse response, String failureMessage) {
|
||||
public Item(SearchResponse response, Throwable throwable) {
|
||||
this.response = response;
|
||||
this.failureMessage = failureMessage;
|
||||
this.throwable = throwable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is it a failed search?
|
||||
*/
|
||||
public boolean isFailure() {
|
||||
return failureMessage != null;
|
||||
return throwable != null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,7 +68,7 @@ public class MultiSearchResponse extends ActionResponse implements Iterable<Mult
|
|||
*/
|
||||
@Nullable
|
||||
public String getFailureMessage() {
|
||||
return failureMessage;
|
||||
return throwable == null ? null : throwable.getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,7 +91,7 @@ public class MultiSearchResponse extends ActionResponse implements Iterable<Mult
|
|||
this.response = new SearchResponse();
|
||||
response.readFrom(in);
|
||||
} else {
|
||||
failureMessage = in.readString();
|
||||
throwable = in.readThrowable();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,9 +102,13 @@ public class MultiSearchResponse extends ActionResponse implements Iterable<Mult
|
|||
response.writeTo(out);
|
||||
} else {
|
||||
out.writeBoolean(false);
|
||||
out.writeString(failureMessage);
|
||||
out.writeThrowable(throwable);
|
||||
}
|
||||
}
|
||||
|
||||
public Throwable getFailure() {
|
||||
return throwable;
|
||||
}
|
||||
}
|
||||
|
||||
private Item[] items;
|
||||
|
@ -150,7 +156,19 @@ public class MultiSearchResponse extends ActionResponse implements Iterable<Mult
|
|||
for (Item item : items) {
|
||||
if (item.isFailure()) {
|
||||
builder.startObject();
|
||||
builder.field(Fields.ERROR, item.getFailureMessage());
|
||||
builder.startObject(Fields.ERROR);
|
||||
final Throwable t = item.getFailure();
|
||||
final ElasticsearchException[] rootCauses = ElasticsearchException.guessRootCauses(t);
|
||||
builder.field(Fields.ROOT_CAUSE);
|
||||
builder.startArray();
|
||||
for (ElasticsearchException rootCause : rootCauses){
|
||||
builder.startObject();
|
||||
rootCause.toXContent(builder, new ToXContent.DelegatingMapParams(Collections.singletonMap(ElasticsearchException.REST_EXCEPTION_SKIP_CAUSE, "true"), params));
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endArray();
|
||||
ElasticsearchException.toXContent(builder, params, t);
|
||||
builder.endObject();
|
||||
builder.endObject();
|
||||
} else {
|
||||
builder.startObject();
|
||||
|
@ -165,6 +183,7 @@ public class MultiSearchResponse extends ActionResponse implements Iterable<Mult
|
|||
static final class Fields {
|
||||
static final XContentBuilderString RESPONSES = new XContentBuilderString("responses");
|
||||
static final XContentBuilderString ERROR = new XContentBuilderString("error");
|
||||
static final XContentBuilderString ROOT_CAUSE = new XContentBuilderString("root_cause");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -69,7 +69,7 @@ public class TransportMultiSearchAction extends HandledTransportAction<MultiSear
|
|||
|
||||
@Override
|
||||
public void onFailure(Throwable e) {
|
||||
responses.set(index, new MultiSearchResponse.Item(null, ExceptionsHelper.detailedMessage(e)));
|
||||
responses.set(index, new MultiSearchResponse.Item(null, e));
|
||||
if (counter.decrementAndGet() == 0) {
|
||||
finishHim();
|
||||
}
|
||||
|
|
|
@ -21,9 +21,14 @@ package org.elasticsearch.action.search;
|
|||
|
||||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.common.io.Streams;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
|
@ -114,4 +119,12 @@ public class MultiSearchRequestTests extends ElasticsearchTestCase {
|
|||
assertThat(request.requests().get(2).types()[1], equalTo("type1"));
|
||||
assertThat(request.requests().get(2).routing(), equalTo("123"));
|
||||
}
|
||||
|
||||
public void testResponseErrorToXContent() throws IOException {
|
||||
MultiSearchResponse response = new MultiSearchResponse(new MultiSearchResponse.Item[]{new MultiSearchResponse.Item(null, new IllegalStateException("foobar")), new MultiSearchResponse.Item(null, new IllegalStateException("baaaaaazzzz"))});
|
||||
XContentBuilder builder = XContentFactory.jsonBuilder();
|
||||
response.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
||||
assertEquals("\"responses\"[{\"error\":{\"root_cause\":[{\"type\":\"illegal_state_exception\",\"reason\":\"foobar\"}],\"type\":\"illegal_state_exception\",\"reason\":\"foobar\"}},{\"error\":{\"root_cause\":[{\"type\":\"illegal_state_exception\",\"reason\":\"baaaaaazzzz\"}],\"type\":\"illegal_state_exception\",\"reason\":\"baaaaaazzzz\"}}]",
|
||||
builder.string());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,9 @@
|
|||
match: {foo: bar}
|
||||
|
||||
- match: { responses.0.hits.total: 3 }
|
||||
- match: { responses.1.error: "/IndexMissingException.no.such.index./" }
|
||||
- match: { responses.1.error.root_cause.0.type: index_missing_exception }
|
||||
- match: { responses.1.error.root_cause.0.reason: "/no.such.index/" }
|
||||
- match: { responses.1.error.root_cause.0.index: test_2 }
|
||||
- match: { responses.2.hits.total: 1 }
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue