mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-09 06:25:07 +00:00
Simplify ElasticsearchException rendering as a XContent (#22611)
This commit tries to simplify the way ElasticsearchException are rendered to xcontent. It adds some documentation and renames and merges some methods. Current behavior is preserved, the goal is to be more readable and centralize everything in the ElasticsearchException class.
This commit is contained in:
parent
e0f8d88d5c
commit
f5542ed47f
@ -22,6 +22,7 @@ package org.elasticsearch;
|
|||||||
import org.elasticsearch.action.support.replication.ReplicationOperation;
|
import org.elasticsearch.action.support.replication.ReplicationOperation;
|
||||||
import org.elasticsearch.cluster.action.shard.ShardStateAction;
|
import org.elasticsearch.cluster.action.shard.ShardStateAction;
|
||||||
import org.elasticsearch.common.CheckedFunction;
|
import org.elasticsearch.common.CheckedFunction;
|
||||||
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.io.stream.Writeable;
|
import org.elasticsearch.common.io.stream.Writeable;
|
||||||
@ -36,13 +37,15 @@ import org.elasticsearch.transport.TcpTransport;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyMap;
|
||||||
|
import static java.util.Collections.singletonMap;
|
||||||
import static java.util.Collections.unmodifiableMap;
|
import static java.util.Collections.unmodifiableMap;
|
||||||
import static org.elasticsearch.cluster.metadata.IndexMetaData.INDEX_UUID_NA_VALUE;
|
import static org.elasticsearch.cluster.metadata.IndexMetaData.INDEX_UUID_NA_VALUE;
|
||||||
import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken;
|
import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken;
|
||||||
@ -56,19 +59,19 @@ public class ElasticsearchException extends RuntimeException implements ToXConte
|
|||||||
static final Version UNKNOWN_VERSION_ADDED = Version.fromId(0);
|
static final Version UNKNOWN_VERSION_ADDED = Version.fromId(0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Passed in the {@link Params} of {@link #toXContent(XContentBuilder, org.elasticsearch.common.xcontent.ToXContent.Params, Throwable)}
|
* Passed in the {@link Params} of {@link #generateThrowableXContent(XContentBuilder, Params, Throwable)}
|
||||||
* to control if the {@code caused_by} element should render. Unlike most parameters to {@code toXContent} methods this parameter is
|
* to control if the {@code caused_by} element should render. Unlike most parameters to {@code toXContent} methods this parameter is
|
||||||
* internal only and not available as a URL parameter.
|
* internal only and not available as a URL parameter.
|
||||||
*/
|
*/
|
||||||
public static final String REST_EXCEPTION_SKIP_CAUSE = "rest.exception.cause.skip";
|
public static final String REST_EXCEPTION_SKIP_CAUSE = "rest.exception.cause.skip";
|
||||||
/**
|
/**
|
||||||
* Passed in the {@link Params} of {@link #toXContent(XContentBuilder, org.elasticsearch.common.xcontent.ToXContent.Params, Throwable)}
|
* Passed in the {@link Params} of {@link #generateThrowableXContent(XContentBuilder, Params, Throwable)}
|
||||||
* to control if the {@code stack_trace} element should render. Unlike most parameters to {@code toXContent} methods this parameter is
|
* to control if the {@code stack_trace} element should render. Unlike most parameters to {@code toXContent} methods this parameter is
|
||||||
* internal only and not available as a URL parameter. Use the {@code error_trace} parameter instead.
|
* internal only and not available as a URL parameter. Use the {@code error_trace} parameter instead.
|
||||||
*/
|
*/
|
||||||
public static final String REST_EXCEPTION_SKIP_STACK_TRACE = "rest.exception.stacktrace.skip";
|
public static final String REST_EXCEPTION_SKIP_STACK_TRACE = "rest.exception.stacktrace.skip";
|
||||||
public static final boolean REST_EXCEPTION_SKIP_STACK_TRACE_DEFAULT = true;
|
public static final boolean REST_EXCEPTION_SKIP_STACK_TRACE_DEFAULT = true;
|
||||||
public static final boolean REST_EXCEPTION_SKIP_CAUSE_DEFAULT = false;
|
private static final boolean REST_EXCEPTION_SKIP_CAUSE_DEFAULT = false;
|
||||||
private static final String INDEX_HEADER_KEY = "es.index";
|
private static final String INDEX_HEADER_KEY = "es.index";
|
||||||
private static final String INDEX_HEADER_KEY_UUID = "es.index_uuid";
|
private static final String INDEX_HEADER_KEY_UUID = "es.index_uuid";
|
||||||
private static final String SHARD_HEADER_KEY = "es.shard";
|
private static final String SHARD_HEADER_KEY = "es.shard";
|
||||||
@ -160,6 +163,10 @@ public class ElasticsearchException extends RuntimeException implements ToXConte
|
|||||||
return headers.get(key);
|
return headers.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Map<String, List<String>> getHeaders() {
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the rest status code associated with this exception.
|
* Returns the rest status code associated with this exception.
|
||||||
*/
|
*/
|
||||||
@ -257,64 +264,56 @@ public class ElasticsearchException extends RuntimeException implements ToXConte
|
|||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
Throwable ex = ExceptionsHelper.unwrapCause(this);
|
Throwable ex = ExceptionsHelper.unwrapCause(this);
|
||||||
if (ex != this) {
|
if (ex != this) {
|
||||||
toXContent(builder, params, this);
|
generateThrowableXContent(builder, params, this);
|
||||||
} else {
|
} else {
|
||||||
builder.field(TYPE, getExceptionName());
|
innerToXContent(builder, params, this, getExceptionName(), getMessage(), headers, getCause());
|
||||||
builder.field(REASON, getMessage());
|
|
||||||
for (String key : headers.keySet()) {
|
|
||||||
if (key.startsWith("es.")) {
|
|
||||||
List<String> values = headers.get(key);
|
|
||||||
xContentHeader(builder, key.substring("es.".length()), values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
innerToXContent(builder, params);
|
|
||||||
renderHeader(builder, params);
|
|
||||||
if (params.paramAsBoolean(REST_EXCEPTION_SKIP_STACK_TRACE, REST_EXCEPTION_SKIP_STACK_TRACE_DEFAULT) == false) {
|
|
||||||
builder.field(STACK_TRACE, ExceptionsHelper.stackTrace(this));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected static void innerToXContent(XContentBuilder builder, Params params,
|
||||||
* Renders additional per exception information into the xcontent
|
Throwable throwable, String type, String message, Map<String, List<String>> headers,
|
||||||
*/
|
Throwable cause) throws IOException {
|
||||||
protected void innerToXContent(XContentBuilder builder, Params params) throws IOException {
|
builder.field(TYPE, type);
|
||||||
causeToXContent(builder, params);
|
builder.field(REASON, message);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
Set<String> customHeaders = new HashSet<>();
|
||||||
* Renders a cause exception as xcontent
|
|
||||||
*/
|
|
||||||
protected void causeToXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
final Throwable cause = getCause();
|
|
||||||
if (cause != null && params.paramAsBoolean(REST_EXCEPTION_SKIP_CAUSE, REST_EXCEPTION_SKIP_CAUSE_DEFAULT) == false) {
|
|
||||||
builder.field(CAUSED_BY);
|
|
||||||
builder.startObject();
|
|
||||||
toXContent(builder, params, cause);
|
|
||||||
builder.endObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final void renderHeader(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
boolean hasHeader = false;
|
|
||||||
for (String key : headers.keySet()) {
|
for (String key : headers.keySet()) {
|
||||||
if (key.startsWith("es.")) {
|
if (key.startsWith("es.")) {
|
||||||
continue;
|
headerToXContent(builder, key.substring("es.".length()), headers.get(key));
|
||||||
|
} else {
|
||||||
|
customHeaders.add(key);
|
||||||
}
|
}
|
||||||
if (hasHeader == false) {
|
|
||||||
builder.startObject(HEADER);
|
|
||||||
hasHeader = true;
|
|
||||||
}
|
|
||||||
List<String> values = headers.get(key);
|
|
||||||
xContentHeader(builder, key, values);
|
|
||||||
}
|
}
|
||||||
if (hasHeader) {
|
|
||||||
|
if (throwable instanceof ElasticsearchException) {
|
||||||
|
ElasticsearchException exception = (ElasticsearchException) throwable;
|
||||||
|
exception.metadataToXContent(builder, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.paramAsBoolean(REST_EXCEPTION_SKIP_CAUSE, REST_EXCEPTION_SKIP_CAUSE_DEFAULT) == false) {
|
||||||
|
if (cause != null) {
|
||||||
|
builder.field(CAUSED_BY);
|
||||||
|
builder.startObject();
|
||||||
|
generateThrowableXContent(builder, params, cause);
|
||||||
|
builder.endObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (customHeaders.isEmpty() == false) {
|
||||||
|
builder.startObject(HEADER);
|
||||||
|
for (String header : customHeaders) {
|
||||||
|
headerToXContent(builder, header, headers.get(header));
|
||||||
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params.paramAsBoolean(REST_EXCEPTION_SKIP_STACK_TRACE, REST_EXCEPTION_SKIP_STACK_TRACE_DEFAULT) == false) {
|
||||||
|
builder.field(STACK_TRACE, ExceptionsHelper.stackTrace(throwable));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void xContentHeader(XContentBuilder builder, String key, List<String> values) throws IOException {
|
private static void headerToXContent(XContentBuilder builder, String key, List<String> values) throws IOException {
|
||||||
if (values != null && values.isEmpty() == false) {
|
if (values != null && values.isEmpty() == false) {
|
||||||
if (values.size() == 1) {
|
if (values.size() == 1) {
|
||||||
builder.field(key, values.get(0));
|
builder.field(key, values.get(0));
|
||||||
@ -329,25 +328,73 @@ public class ElasticsearchException extends RuntimeException implements ToXConte
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static toXContent helper method that also renders non {@link org.elasticsearch.ElasticsearchException} instances as XContent.
|
* Renders additional per exception information into the XContent
|
||||||
*/
|
*/
|
||||||
public static void toXContent(XContentBuilder builder, Params params, Throwable ex) throws IOException {
|
protected void metadataToXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
ex = ExceptionsHelper.unwrapCause(ex);
|
}
|
||||||
if (ex instanceof ElasticsearchException) {
|
|
||||||
((ElasticsearchException) ex).toXContent(builder, params);
|
/**
|
||||||
|
* Static toXContent helper method that renders {@link org.elasticsearch.ElasticsearchException} or {@link Throwable} instances
|
||||||
|
* as XContent, delegating the rendering to {@link #toXContent(XContentBuilder, Params)}
|
||||||
|
* or {@link #innerToXContent(XContentBuilder, Params, Throwable, String, String, Map, Throwable)}.
|
||||||
|
*
|
||||||
|
* This method is usually used when the {@link Throwable} is rendered as a part of another XContent object.
|
||||||
|
*/
|
||||||
|
public static void generateThrowableXContent(XContentBuilder builder, Params params, Throwable t) throws IOException {
|
||||||
|
t = ExceptionsHelper.unwrapCause(t);
|
||||||
|
|
||||||
|
if (t instanceof ElasticsearchException) {
|
||||||
|
((ElasticsearchException) t).toXContent(builder, params);
|
||||||
} else {
|
} else {
|
||||||
builder.field(TYPE, getExceptionName(ex));
|
innerToXContent(builder, params, t, getExceptionName(t), t.getMessage(), emptyMap(), t.getCause());
|
||||||
builder.field(REASON, ex.getMessage());
|
}
|
||||||
if (ex.getCause() != null) {
|
}
|
||||||
builder.field(CAUSED_BY);
|
|
||||||
|
/**
|
||||||
|
* Render any exception as a xcontent, encapsulated within a field or object named "error". The level of details that are rendered
|
||||||
|
* depends on the value of the "detailed" parameter: when it's false only a simple message based on the type and message of the
|
||||||
|
* exception is rendered. When it's true all detail are provided including guesses root causes, cause and potentially stack
|
||||||
|
* trace.
|
||||||
|
*
|
||||||
|
* This method is usually used when the {@link Exception} is rendered as a full XContent object.
|
||||||
|
*/
|
||||||
|
public static void generateFailureXContent(XContentBuilder builder, Params params, @Nullable Exception e, boolean detailed)
|
||||||
|
throws IOException {
|
||||||
|
// No exception to render as an error
|
||||||
|
if (e == null) {
|
||||||
|
builder.field(ERROR, "unknown");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the exception with a simple message
|
||||||
|
if (detailed == false) {
|
||||||
|
String message = "No ElasticsearchException found";
|
||||||
|
Throwable t = e;
|
||||||
|
for (int counter = 0; counter < 10 && t != null; counter++) {
|
||||||
|
if (t instanceof ElasticsearchException) {
|
||||||
|
message = t.getClass().getSimpleName() + "[" + t.getMessage() + "]";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
t = t.getCause();
|
||||||
|
}
|
||||||
|
builder.field(ERROR, message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the exception with all details
|
||||||
|
final ElasticsearchException[] rootCauses = ElasticsearchException.guessRootCauses(e);
|
||||||
|
builder.startObject(ERROR);
|
||||||
|
{
|
||||||
|
builder.startArray(ROOT_CAUSE);
|
||||||
|
for (ElasticsearchException rootCause : rootCauses) {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
toXContent(builder, params, ex.getCause());
|
rootCause.toXContent(builder, new DelegatingMapParams(singletonMap(REST_EXCEPTION_SKIP_CAUSE, "true"), params));
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
if (params.paramAsBoolean(REST_EXCEPTION_SKIP_STACK_TRACE, REST_EXCEPTION_SKIP_STACK_TRACE_DEFAULT) == false) {
|
builder.endArray();
|
||||||
builder.field(STACK_TRACE, ExceptionsHelper.stackTrace(ex));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
generateThrowableXContent(builder, params, e);
|
||||||
|
builder.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -877,22 +924,6 @@ public class ElasticsearchException extends RuntimeException implements ToXConte
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderException(XContentBuilder builder, Params params, Exception e) throws IOException {
|
|
||||||
builder.startObject(ERROR);
|
|
||||||
final ElasticsearchException[] rootCauses = ElasticsearchException.guessRootCauses(e);
|
|
||||||
builder.field(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, e);
|
|
||||||
builder.endObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
// lower cases and adds underscores to transitions in a name
|
// lower cases and adds underscores to transitions in a name
|
||||||
private static String toUnderscoreCase(String value) {
|
private static String toUnderscoreCase(String value) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
@ -105,7 +105,7 @@ public final class TaskOperationFailure implements Writeable, ToXContent {
|
|||||||
if (reason != null) {
|
if (reason != null) {
|
||||||
builder.field("reason");
|
builder.field("reason");
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
ElasticsearchException.toXContent(builder, params, reason);
|
ElasticsearchException.generateThrowableXContent(builder, params, reason);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
return builder;
|
return builder;
|
||||||
|
@ -207,7 +207,7 @@ public class IndicesShardStoresResponse extends ActionResponse implements ToXCon
|
|||||||
builder.field(Fields.ALLOCATED, allocationStatus.value());
|
builder.field(Fields.ALLOCATED, allocationStatus.value());
|
||||||
if (storeException != null) {
|
if (storeException != null) {
|
||||||
builder.startObject(Fields.STORE_EXCEPTION);
|
builder.startObject(Fields.STORE_EXCEPTION);
|
||||||
ElasticsearchException.toXContent(builder, params, storeException);
|
ElasticsearchException.generateThrowableXContent(builder, params, storeException);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
return builder;
|
return builder;
|
||||||
|
@ -63,7 +63,7 @@ public class BulkItemResponse implements Streamable, StatusToXContentObject {
|
|||||||
builder.field(Fields._ID, failure.getId());
|
builder.field(Fields._ID, failure.getId());
|
||||||
builder.field(Fields.STATUS, failure.getStatus().getStatus());
|
builder.field(Fields.STATUS, failure.getStatus().getStatus());
|
||||||
builder.startObject(Fields.ERROR);
|
builder.startObject(Fields.ERROR);
|
||||||
ElasticsearchException.toXContent(builder, params, failure.getCause());
|
ElasticsearchException.generateThrowableXContent(builder, params, failure.getCause());
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
@ -173,7 +173,7 @@ public class BulkItemResponse implements Streamable, StatusToXContentObject {
|
|||||||
builder.field(ID_FIELD, id);
|
builder.field(ID_FIELD, id);
|
||||||
}
|
}
|
||||||
builder.startObject(CAUSE_FIELD);
|
builder.startObject(CAUSE_FIELD);
|
||||||
ElasticsearchException.toXContent(builder, params, cause);
|
ElasticsearchException.generateThrowableXContent(builder, params, cause);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
builder.field(STATUS_FIELD, status.getStatus());
|
builder.field(STATUS_FIELD, status.getStatus());
|
||||||
return builder;
|
return builder;
|
||||||
|
@ -137,7 +137,7 @@ public class MultiGetResponse extends ActionResponse implements Iterable<MultiGe
|
|||||||
builder.field(Fields._INDEX, failure.getIndex());
|
builder.field(Fields._INDEX, failure.getIndex());
|
||||||
builder.field(Fields._TYPE, failure.getType());
|
builder.field(Fields._TYPE, failure.getType());
|
||||||
builder.field(Fields._ID, failure.getId());
|
builder.field(Fields._ID, failure.getId());
|
||||||
ElasticsearchException.renderException(builder, params, failure.getFailure());
|
ElasticsearchException.generateFailureXContent(builder, params, failure.getFailure(), true);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
} else {
|
} else {
|
||||||
GetResponse getResponse = response.getResponse();
|
GetResponse getResponse = response.getResponse();
|
||||||
|
@ -84,7 +84,7 @@ public final class SimulateDocumentBaseResult implements SimulateDocumentResult
|
|||||||
if (failure == null) {
|
if (failure == null) {
|
||||||
ingestDocument.toXContent(builder, params);
|
ingestDocument.toXContent(builder, params);
|
||||||
} else {
|
} else {
|
||||||
ElasticsearchException.renderException(builder, params, failure);
|
ElasticsearchException.generateFailureXContent(builder, params, failure, true);
|
||||||
}
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
return builder;
|
return builder;
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
package org.elasticsearch.action.ingest;
|
package org.elasticsearch.action.ingest;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.io.stream.Writeable;
|
import org.elasticsearch.common.io.stream.Writeable;
|
||||||
@ -99,10 +98,10 @@ class SimulateProcessorResult implements Writeable, ToXContent {
|
|||||||
|
|
||||||
if (failure != null && ingestDocument != null) {
|
if (failure != null && ingestDocument != null) {
|
||||||
builder.startObject("ignored_error");
|
builder.startObject("ignored_error");
|
||||||
ElasticsearchException.renderException(builder, params, failure);
|
ElasticsearchException.generateFailureXContent(builder, params, failure, true);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
} else if (failure != null) {
|
} else if (failure != null) {
|
||||||
ElasticsearchException.renderException(builder, params, failure);
|
ElasticsearchException.generateFailureXContent(builder, params, failure, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ingestDocument != null) {
|
if (ingestDocument != null) {
|
||||||
|
@ -156,7 +156,7 @@ public class MultiSearchResponse extends ActionResponse implements Iterable<Mult
|
|||||||
for (Item item : items) {
|
for (Item item : items) {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
if (item.isFailure()) {
|
if (item.isFailure()) {
|
||||||
ElasticsearchException.renderException(builder, params, item.getFailure());
|
ElasticsearchException.generateFailureXContent(builder, params, item.getFailure(), true);
|
||||||
builder.field(Fields.STATUS, ExceptionsHelper.status(item.getFailure()).getStatus());
|
builder.field(Fields.STATUS, ExceptionsHelper.status(item.getFailure()).getStatus());
|
||||||
} else {
|
} else {
|
||||||
item.getResponse().innerToXContent(builder, params);
|
item.getResponse().innerToXContent(builder, params);
|
||||||
|
@ -103,6 +103,7 @@ public class SearchPhaseExecutionException extends ElasticsearchException {
|
|||||||
return shardFailures;
|
return shardFailures;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Throwable getCause() {
|
public Throwable getCause() {
|
||||||
Throwable cause = super.getCause();
|
Throwable cause = super.getCause();
|
||||||
if (cause == null) {
|
if (cause == null) {
|
||||||
@ -131,7 +132,7 @@ public class SearchPhaseExecutionException extends ElasticsearchException {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void innerToXContent(XContentBuilder builder, Params params) throws IOException {
|
protected void metadataToXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.field("phase", phaseName);
|
builder.field("phase", phaseName);
|
||||||
final boolean group = params.paramAsBoolean("group_shard_failures", true); // we group by default
|
final boolean group = params.paramAsBoolean("group_shard_failures", true); // we group by default
|
||||||
builder.field("grouped", group); // notify that it's grouped
|
builder.field("grouped", group); // notify that it's grouped
|
||||||
@ -144,15 +145,20 @@ public class SearchPhaseExecutionException extends ElasticsearchException {
|
|||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
builder.endArray();
|
builder.endArray();
|
||||||
super.innerToXContent(builder, params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void causeToXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
if (super.getCause() != null) {
|
Throwable ex = ExceptionsHelper.unwrapCause(this);
|
||||||
// if the cause is null we inject a guessed root cause that will then be rendered twice so wi disable it manually
|
if (ex != this) {
|
||||||
super.causeToXContent(builder, params);
|
generateThrowableXContent(builder, params, this);
|
||||||
|
} else {
|
||||||
|
// We don't have a cause when all shards failed, but we do have shards failures so we can "guess" a cause
|
||||||
|
// (see {@link #getCause()}). Here, we use super.getCause() because we don't want the guessed exception to
|
||||||
|
// be rendered twice (one in the "cause" field, one in "failed_shards")
|
||||||
|
innerToXContent(builder, params, this, getExceptionName(), getMessage(), getHeaders(), super.getCause());
|
||||||
}
|
}
|
||||||
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -161,7 +161,7 @@ public class ShardSearchFailure implements ShardOperationFailedException {
|
|||||||
if (cause != null) {
|
if (cause != null) {
|
||||||
builder.field("reason");
|
builder.field("reason");
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
ElasticsearchException.toXContent(builder, params, cause);
|
ElasticsearchException.generateThrowableXContent(builder, params, cause);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
return builder;
|
return builder;
|
||||||
|
@ -125,7 +125,7 @@ public class DefaultShardOperationFailedException implements ShardOperationFaile
|
|||||||
if (reason != null) {
|
if (reason != null) {
|
||||||
builder.field("reason");
|
builder.field("reason");
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
ElasticsearchException.toXContent(builder, params, reason);
|
ElasticsearchException.generateThrowableXContent(builder, params, reason);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
return builder;
|
return builder;
|
||||||
|
@ -28,7 +28,6 @@ import org.elasticsearch.common.Nullable;
|
|||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.io.stream.Streamable;
|
import org.elasticsearch.common.io.stream.Streamable;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
|
||||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
@ -375,7 +374,7 @@ public class ReplicationResponse extends ActionResponse {
|
|||||||
builder.field(_NODE, nodeId);
|
builder.field(_NODE, nodeId);
|
||||||
builder.field(REASON);
|
builder.field(REASON);
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
ElasticsearchException.toXContent(builder, params, cause);
|
ElasticsearchException.generateThrowableXContent(builder, params, cause);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
builder.field(STATUS, status);
|
builder.field(STATUS, status);
|
||||||
builder.field(PRIMARY, primary);
|
builder.field(PRIMARY, primary);
|
||||||
|
@ -133,7 +133,7 @@ public class MultiTermVectorsResponse extends ActionResponse implements Iterable
|
|||||||
builder.field(Fields._INDEX, failure.getIndex());
|
builder.field(Fields._INDEX, failure.getIndex());
|
||||||
builder.field(Fields._TYPE, failure.getType());
|
builder.field(Fields._TYPE, failure.getType());
|
||||||
builder.field(Fields._ID, failure.getId());
|
builder.field(Fields._ID, failure.getId());
|
||||||
ElasticsearchException.renderException(builder, params, failure.getCause());
|
ElasticsearchException.generateFailureXContent(builder, params, failure.getCause(), true);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
} else {
|
} else {
|
||||||
TermVectorsResponse getResponse = response.getResponse();
|
TermVectorsResponse getResponse = response.getResponse();
|
||||||
|
@ -262,7 +262,7 @@ public class NodeAllocationResult implements ToXContent, Writeable, Comparable<N
|
|||||||
}
|
}
|
||||||
if (storeException != null) {
|
if (storeException != null) {
|
||||||
builder.startObject("store_exception");
|
builder.startObject("store_exception");
|
||||||
ElasticsearchException.toXContent(builder, params, storeException);
|
ElasticsearchException.generateThrowableXContent(builder, params, storeException);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,12 +95,11 @@ public class ParsingException extends ElasticsearchException {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void innerToXContent(XContentBuilder builder, Params params) throws IOException {
|
protected void metadataToXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
if (lineNumber != UNKNOWN_POSITION) {
|
if (lineNumber != UNKNOWN_POSITION) {
|
||||||
builder.field("line", lineNumber);
|
builder.field("line", lineNumber);
|
||||||
builder.field("col", columnNumber);
|
builder.field("col", columnNumber);
|
||||||
}
|
}
|
||||||
super.innerToXContent(builder, params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -73,9 +73,8 @@ public class CircuitBreakingException extends ElasticsearchException {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void innerToXContent(XContentBuilder builder, Params params) throws IOException {
|
protected void metadataToXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.field("bytes_wanted", bytesWanted);
|
builder.field("bytes_wanted", bytesWanted);
|
||||||
builder.field("bytes_limit", byteLimit);
|
builder.field("bytes_limit", byteLimit);
|
||||||
super.innerToXContent(builder, params);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@ package org.elasticsearch.index.query;
|
|||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.index.Index;
|
import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
|
|
||||||
@ -60,11 +59,6 @@ public class QueryShardException extends ElasticsearchException {
|
|||||||
return RestStatus.BAD_REQUEST;
|
return RestStatus.BAD_REQUEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void innerToXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
super.innerToXContent(builder, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
super.writeTo(out);
|
super.writeTo(out);
|
||||||
|
@ -31,7 +31,10 @@ import org.elasticsearch.common.xcontent.ToXContent;
|
|||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
|
||||||
|
import static java.util.Collections.singletonMap;
|
||||||
|
import static org.elasticsearch.ElasticsearchException.REST_EXCEPTION_SKIP_STACK_TRACE;
|
||||||
|
import static org.elasticsearch.ElasticsearchException.REST_EXCEPTION_SKIP_STACK_TRACE_DEFAULT;
|
||||||
|
|
||||||
|
|
||||||
public class BytesRestResponse extends RestResponse {
|
public class BytesRestResponse extends RestResponse {
|
||||||
@ -89,7 +92,7 @@ public class BytesRestResponse extends RestResponse {
|
|||||||
this.content = BytesArray.EMPTY;
|
this.content = BytesArray.EMPTY;
|
||||||
this.contentType = TEXT_CONTENT_TYPE;
|
this.contentType = TEXT_CONTENT_TYPE;
|
||||||
} else {
|
} else {
|
||||||
try (final XContentBuilder builder = convert(channel, status, e)) {
|
try (final XContentBuilder builder = build(channel, status, e)) {
|
||||||
this.content = builder.bytes();
|
this.content = builder.bytes();
|
||||||
this.contentType = builder.contentType().mediaType();
|
this.contentType = builder.contentType().mediaType();
|
||||||
}
|
}
|
||||||
@ -116,49 +119,25 @@ public class BytesRestResponse extends RestResponse {
|
|||||||
|
|
||||||
private static final Logger SUPPRESSED_ERROR_LOGGER = ESLoggerFactory.getLogger("rest.suppressed");
|
private static final Logger SUPPRESSED_ERROR_LOGGER = ESLoggerFactory.getLogger("rest.suppressed");
|
||||||
|
|
||||||
private static XContentBuilder convert(RestChannel channel, RestStatus status, Exception e) throws IOException {
|
private static XContentBuilder build(RestChannel channel, RestStatus status, Exception e) throws IOException {
|
||||||
XContentBuilder builder = channel.newErrorBuilder().startObject();
|
ToXContent.Params params = channel.request();
|
||||||
if (e == null) {
|
if (params.paramAsBoolean("error_trace", !REST_EXCEPTION_SKIP_STACK_TRACE_DEFAULT)) {
|
||||||
builder.field("error", "unknown");
|
params = new ToXContent.DelegatingMapParams(singletonMap(REST_EXCEPTION_SKIP_STACK_TRACE, "false"), params);
|
||||||
} else if (channel.detailedErrorsEnabled()) {
|
} else if (e != null) {
|
||||||
final ToXContent.Params params;
|
Supplier<?> messageSupplier = () -> new ParameterizedMessage("path: {}, params: {}",
|
||||||
if (channel.request().paramAsBoolean("error_trace", !ElasticsearchException.REST_EXCEPTION_SKIP_STACK_TRACE_DEFAULT)) {
|
channel.request().rawPath(), channel.request().params());
|
||||||
params = new ToXContent.DelegatingMapParams(
|
|
||||||
Collections.singletonMap(ElasticsearchException.REST_EXCEPTION_SKIP_STACK_TRACE, "false"), channel.request());
|
if (status.getStatus() < 500) {
|
||||||
|
SUPPRESSED_ERROR_LOGGER.debug(messageSupplier, e);
|
||||||
} else {
|
} else {
|
||||||
if (status.getStatus() < 500) {
|
SUPPRESSED_ERROR_LOGGER.warn(messageSupplier, e);
|
||||||
SUPPRESSED_ERROR_LOGGER.debug(
|
|
||||||
(Supplier<?>) () -> new ParameterizedMessage("path: {}, params: {}",
|
|
||||||
channel.request().rawPath(), channel.request().params()), e);
|
|
||||||
} else {
|
|
||||||
SUPPRESSED_ERROR_LOGGER.warn(
|
|
||||||
(Supplier<?>) () -> new ParameterizedMessage("path: {}, params: {}",
|
|
||||||
channel.request().rawPath(), channel.request().params()), e);
|
|
||||||
}
|
|
||||||
params = channel.request();
|
|
||||||
}
|
}
|
||||||
ElasticsearchException.renderException(builder, params, e);
|
|
||||||
} else {
|
|
||||||
builder.field("error", simpleMessage(e));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XContentBuilder builder = channel.newErrorBuilder().startObject();
|
||||||
|
ElasticsearchException.generateFailureXContent(builder, params, e, channel.detailedErrorsEnabled());
|
||||||
builder.field("status", status.getStatus());
|
builder.field("status", status.getStatus());
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Builds a simple error string from the message of the first ElasticsearchException
|
|
||||||
*/
|
|
||||||
private static String simpleMessage(Throwable t) throws IOException {
|
|
||||||
int counter = 0;
|
|
||||||
Throwable next = t;
|
|
||||||
while (next != null && counter++ < 10) {
|
|
||||||
if (t instanceof ElasticsearchException) {
|
|
||||||
return next.getClass().getSimpleName() + "[" + next.getMessage() + "]";
|
|
||||||
}
|
|
||||||
next = next.getCause();
|
|
||||||
}
|
|
||||||
|
|
||||||
return "No ElasticsearchException found";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -87,8 +87,7 @@ public class ScriptException extends ElasticsearchException {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void innerToXContent(XContentBuilder builder, Params params) throws IOException {
|
protected void metadataToXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
super.innerToXContent(builder, params);
|
|
||||||
builder.field("script_stack", scriptStack);
|
builder.field("script_stack", scriptStack);
|
||||||
builder.field("script", script);
|
builder.field("script", script);
|
||||||
builder.field("lang", lang);
|
builder.field("lang", lang);
|
||||||
|
@ -607,7 +607,7 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
|||||||
try (XContentBuilder builder = JsonXContent.contentBuilder()) {
|
try (XContentBuilder builder = JsonXContent.contentBuilder()) {
|
||||||
builder.prettyPrint();
|
builder.prettyPrint();
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
ElasticsearchException.toXContent(builder, ToXContent.EMPTY_PARAMS, e);
|
ElasticsearchException.generateThrowableXContent(builder, ToXContent.EMPTY_PARAMS, e);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
logger.warn("failed to load/compile script [{}]: {}", scriptNameExt.v1(), builder.string());
|
logger.warn("failed to load/compile script [{}]: {}", scriptNameExt.v1(), builder.string());
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
|
@ -72,12 +72,11 @@ public class SearchParseException extends SearchContextException {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void innerToXContent(XContentBuilder builder, Params params) throws IOException {
|
protected void metadataToXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
if (lineNumber != UNKNOWN_POSITION) {
|
if (lineNumber != UNKNOWN_POSITION) {
|
||||||
builder.field("line", lineNumber);
|
builder.field("line", lineNumber);
|
||||||
builder.field("col", columnNumber);
|
builder.field("col", columnNumber);
|
||||||
}
|
}
|
||||||
super.innerToXContent(builder, params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -230,7 +230,7 @@ public final class TaskResult implements Writeable, ToXContent {
|
|||||||
private static BytesReference toXContent(Exception error) throws IOException {
|
private static BytesReference toXContent(Exception error) throws IOException {
|
||||||
try (XContentBuilder builder = XContentFactory.contentBuilder(Requests.INDEX_CONTENT_TYPE)) {
|
try (XContentBuilder builder = XContentFactory.contentBuilder(Requests.INDEX_CONTENT_TYPE)) {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
ElasticsearchException.toXContent(builder, ToXContent.EMPTY_PARAMS, error);
|
ElasticsearchException.generateThrowableXContent(builder, ToXContent.EMPTY_PARAMS, error);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
return builder.bytes();
|
return builder.bytes();
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,7 @@ public class ESExceptionTests extends ESTestCase {
|
|||||||
}
|
}
|
||||||
XContentBuilder builder = XContentFactory.jsonBuilder();
|
XContentBuilder builder = XContentFactory.jsonBuilder();
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
ElasticsearchException.toXContent(builder, PARAMS, ex);
|
ElasticsearchException.generateThrowableXContent(builder, PARAMS, ex);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
|
|
||||||
String expected = "{\"type\":\"file_not_found_exception\",\"reason\":\"foo not found\"}";
|
String expected = "{\"type\":\"file_not_found_exception\",\"reason\":\"foo not found\"}";
|
||||||
@ -264,7 +264,7 @@ public class ESExceptionTests extends ESTestCase {
|
|||||||
ParsingException ex = new ParsingException(1, 2, "foobar", null);
|
ParsingException ex = new ParsingException(1, 2, "foobar", null);
|
||||||
XContentBuilder builder = XContentFactory.jsonBuilder();
|
XContentBuilder builder = XContentFactory.jsonBuilder();
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
ElasticsearchException.toXContent(builder, PARAMS, ex);
|
ElasticsearchException.generateThrowableXContent(builder, PARAMS, ex);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
String expected = "{\"type\":\"parsing_exception\",\"reason\":\"foobar\",\"line\":1,\"col\":2}";
|
String expected = "{\"type\":\"parsing_exception\",\"reason\":\"foobar\",\"line\":1,\"col\":2}";
|
||||||
assertEquals(expected, builder.string());
|
assertEquals(expected, builder.string());
|
||||||
@ -274,7 +274,7 @@ public class ESExceptionTests extends ESTestCase {
|
|||||||
ElasticsearchException ex = new RemoteTransportException("foobar", new FileNotFoundException("foo not found"));
|
ElasticsearchException ex = new RemoteTransportException("foobar", new FileNotFoundException("foo not found"));
|
||||||
XContentBuilder builder = XContentFactory.jsonBuilder();
|
XContentBuilder builder = XContentFactory.jsonBuilder();
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
ElasticsearchException.toXContent(builder, PARAMS, ex);
|
ElasticsearchException.generateThrowableXContent(builder, PARAMS, ex);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
|
|
||||||
XContentBuilder otherBuilder = XContentFactory.jsonBuilder();
|
XContentBuilder otherBuilder = XContentFactory.jsonBuilder();
|
||||||
@ -292,7 +292,7 @@ public class ESExceptionTests extends ESTestCase {
|
|||||||
ex.addHeader("test_multi", "some value", "another value");
|
ex.addHeader("test_multi", "some value", "another value");
|
||||||
XContentBuilder builder = XContentFactory.jsonBuilder();
|
XContentBuilder builder = XContentFactory.jsonBuilder();
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
ElasticsearchException.toXContent(builder, PARAMS, ex);
|
ElasticsearchException.generateThrowableXContent(builder, PARAMS, ex);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
assertThat(builder.string(), Matchers.anyOf( // iteration order depends on platform
|
assertThat(builder.string(), Matchers.anyOf( // iteration order depends on platform
|
||||||
equalTo("{\"type\":\"parsing_exception\",\"reason\":\"foobar\",\"line\":1,\"col\":2,\"header\":{\"test_multi\":[\"some value\",\"another value\"],\"test\":\"some value\"}}"),
|
equalTo("{\"type\":\"parsing_exception\",\"reason\":\"foobar\",\"line\":1,\"col\":2,\"header\":{\"test_multi\":[\"some value\",\"another value\"],\"test\":\"some value\"}}"),
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package org.elasticsearch;
|
package org.elasticsearch;
|
||||||
|
|
||||||
|
import org.apache.lucene.util.Constants;
|
||||||
import org.elasticsearch.action.RoutingMissingException;
|
import org.elasticsearch.action.RoutingMissingException;
|
||||||
import org.elasticsearch.action.support.broadcast.BroadcastShardOperationFailedException;
|
import org.elasticsearch.action.support.broadcast.BroadcastShardOperationFailedException;
|
||||||
import org.elasticsearch.cluster.block.ClusterBlockException;
|
import org.elasticsearch.cluster.block.ClusterBlockException;
|
||||||
@ -67,7 +68,9 @@ public class ElasticsearchExceptionTests extends ESTestCase {
|
|||||||
// in the JSON. Since the stack can be large, it only checks the beginning of the JSON.
|
// 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\"," +
|
assertExceptionAsJson(e, true, startsWith("{\"type\":\"exception\",\"reason\":\"foo\"," +
|
||||||
"\"caused_by\":{\"type\":\"illegal_state_exception\",\"reason\":\"bar\"," +
|
"\"caused_by\":{\"type\":\"illegal_state_exception\",\"reason\":\"bar\"," +
|
||||||
"\"stack_trace\":\"java.lang.IllegalStateException: bar"));
|
"\"stack_trace\":\"java.lang.IllegalStateException: bar" +
|
||||||
|
(Constants.WINDOWS ? "\\r\\n" : "\\n") +
|
||||||
|
"\\tat org.elasticsearch."));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testToXContentWithHeaders() throws IOException {
|
public void testToXContentWithHeaders() throws IOException {
|
||||||
|
@ -152,7 +152,7 @@ public class MultiSearchTemplateResponse extends ActionResponse implements Itera
|
|||||||
for (Item item : items) {
|
for (Item item : items) {
|
||||||
if (item.isFailure()) {
|
if (item.isFailure()) {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
ElasticsearchException.renderException(builder, params, item.getFailure());
|
ElasticsearchException.generateFailureXContent(builder, params, item.getFailure(), true);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
} else {
|
} else {
|
||||||
item.getResponse().toXContent(builder, params);
|
item.getResponse().toXContent(builder, params);
|
||||||
|
@ -486,7 +486,7 @@ public abstract class BulkByScrollTask extends CancellableTask {
|
|||||||
status.toXContent(builder, params);
|
status.toXContent(builder, params);
|
||||||
} else {
|
} else {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
ElasticsearchException.toXContent(builder, params, exception);
|
ElasticsearchException.generateThrowableXContent(builder, params, exception);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
return builder;
|
return builder;
|
||||||
|
@ -348,7 +348,7 @@ public abstract class ScrollableHitSource implements Closeable {
|
|||||||
builder.field("reason");
|
builder.field("reason");
|
||||||
{
|
{
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
ElasticsearchException.toXContent(builder, params, reason);
|
ElasticsearchException.generateThrowableXContent(builder, params, reason);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user