12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190 |
- /*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- package org.elasticsearch;
- import org.elasticsearch.action.support.replication.ReplicationOperation;
- import org.elasticsearch.cluster.action.shard.ShardStateAction;
- import org.elasticsearch.common.CheckedFunction;
- import org.elasticsearch.common.Nullable;
- import org.elasticsearch.common.ParseField;
- import org.elasticsearch.common.collect.Tuple;
- import org.elasticsearch.common.io.stream.StreamInput;
- import org.elasticsearch.common.io.stream.StreamOutput;
- import org.elasticsearch.common.io.stream.Writeable;
- import org.elasticsearch.common.logging.LoggerMessageFormat;
- import org.elasticsearch.common.xcontent.ToXContentFragment;
- import org.elasticsearch.common.xcontent.XContentBuilder;
- import org.elasticsearch.common.xcontent.XContentParseException;
- import org.elasticsearch.common.xcontent.XContentParser;
- import org.elasticsearch.index.Index;
- import org.elasticsearch.index.shard.ShardId;
- import org.elasticsearch.rest.RestStatus;
- import org.elasticsearch.search.SearchException;
- import org.elasticsearch.search.aggregations.MultiBucketConsumerService;
- import org.elasticsearch.transport.TcpTransport;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- 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 org.elasticsearch.cluster.metadata.IndexMetadata.INDEX_UUID_NA_VALUE;
- import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken;
- import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureFieldName;
- /**
- * A base class for all elasticsearch exceptions.
- */
- public class ElasticsearchException extends RuntimeException implements ToXContentFragment, Writeable {
- private static final Version UNKNOWN_VERSION_ADDED = Version.fromId(0);
- /**
- * 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
- * internal only and not available as a URL parameter.
- */
- private static final String REST_EXCEPTION_SKIP_CAUSE = "rest.exception.cause.skip";
- /**
- * 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
- * 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 boolean REST_EXCEPTION_SKIP_STACK_TRACE_DEFAULT = true;
- private static final boolean REST_EXCEPTION_SKIP_CAUSE_DEFAULT = false;
- private static final String INDEX_METADATA_KEY = "es.index";
- private static final String INDEX_METADATA_KEY_UUID = "es.index_uuid";
- private static final String SHARD_METADATA_KEY = "es.shard";
- private static final String RESOURCE_METADATA_TYPE_KEY = "es.resource.type";
- private static final String RESOURCE_METADATA_ID_KEY = "es.resource.id";
- private static final String TYPE = "type";
- private static final String REASON = "reason";
- private static final String CAUSED_BY = "caused_by";
- private static final ParseField SUPPRESSED = new ParseField("suppressed");
- public static final String STACK_TRACE = "stack_trace";
- private static final String HEADER = "header";
- private static final String ERROR = "error";
- private static final String ROOT_CAUSE = "root_cause";
- private static final Map<Integer, CheckedFunction<StreamInput, ? extends ElasticsearchException, IOException>> ID_TO_SUPPLIER;
- private static final Map<Class<? extends ElasticsearchException>, ElasticsearchExceptionHandle> CLASS_TO_ELASTICSEARCH_EXCEPTION_HANDLE;
- private final Map<String, List<String>> metadata = new HashMap<>();
- private final Map<String, List<String>> headers = new HashMap<>();
- /**
- * Construct a <code>ElasticsearchException</code> with the specified cause exception.
- */
- public ElasticsearchException(Throwable cause) {
- super(cause);
- }
- /**
- * Construct a <code>ElasticsearchException</code> with the specified detail message.
- *
- * The message can be parameterized using <code>{}</code> as placeholders for the given
- * arguments
- *
- * @param msg the detail message
- * @param args the arguments for the message
- */
- public ElasticsearchException(String msg, Object... args) {
- super(LoggerMessageFormat.format(msg, args));
- }
- /**
- * Construct a <code>ElasticsearchException</code> with the specified detail message
- * and nested exception.
- *
- * The message can be parameterized using <code>{}</code> as placeholders for the given
- * arguments
- *
- * @param msg the detail message
- * @param cause the nested exception
- * @param args the arguments for the message
- */
- public ElasticsearchException(String msg, Throwable cause, Object... args) {
- super(LoggerMessageFormat.format(msg, args), cause);
- }
- public ElasticsearchException(StreamInput in) throws IOException {
- super(in.readOptionalString(), in.readException());
- readStackTrace(this, in);
- headers.putAll(in.readMapOfLists(StreamInput::readString, StreamInput::readString));
- metadata.putAll(in.readMapOfLists(StreamInput::readString, StreamInput::readString));
- }
- /**
- * Adds a new piece of metadata with the given key.
- * If the provided key is already present, the corresponding metadata will be replaced
- */
- public void addMetadata(String key, String... values) {
- addMetadata(key, Arrays.asList(values));
- }
- /**
- * Adds a new piece of metadata with the given key.
- * If the provided key is already present, the corresponding metadata will be replaced
- */
- public void addMetadata(String key, List<String> values) {
- //we need to enforce this otherwise bw comp doesn't work properly, as "es." was the previous criteria to split headers in two sets
- if (key.startsWith("es.") == false) {
- throw new IllegalArgumentException("exception metadata must start with [es.], found [" + key + "] instead");
- }
- this.metadata.put(key, values);
- }
- /**
- * Returns a set of all metadata keys on this exception
- */
- public Set<String> getMetadataKeys() {
- return metadata.keySet();
- }
- /**
- * Returns the list of metadata values for the given key or {@code null} if no metadata for the
- * given key exists.
- */
- public List<String> getMetadata(String key) {
- return metadata.get(key);
- }
- protected Map<String, List<String>> getMetadata() {
- return metadata;
- }
- /**
- * Adds a new header with the given key.
- * This method will replace existing header if a header with the same key already exists
- */
- public void addHeader(String key, List<String> value) {
- //we need to enforce this otherwise bw comp doesn't work properly, as "es." was the previous criteria to split headers in two sets
- if (key.startsWith("es.")) {
- throw new IllegalArgumentException("exception headers must not start with [es.], found [" + key + "] instead");
- }
- this.headers.put(key, value);
- }
- /**
- * Adds a new header with the given key.
- * This method will replace existing header if a header with the same key already exists
- */
- public void addHeader(String key, String... value) {
- addHeader(key, Arrays.asList(value));
- }
- /**
- * Returns a set of all header keys on this exception
- */
- public Set<String> getHeaderKeys() {
- return headers.keySet();
- }
- /**
- * Returns the list of header values for the given key or {@code null} if no header for the
- * given key exists.
- */
- public List<String> getHeader(String key) {
- return headers.get(key);
- }
- protected Map<String, List<String>> getHeaders() {
- return headers;
- }
- /**
- * Returns the rest status code associated with this exception.
- */
- public RestStatus status() {
- Throwable cause = unwrapCause();
- if (cause == this) {
- return RestStatus.INTERNAL_SERVER_ERROR;
- } else {
- return ExceptionsHelper.status(cause);
- }
- }
- /**
- * Unwraps the actual cause from the exception for cases when the exception is a
- * {@link ElasticsearchWrapperException}.
- *
- * @see ExceptionsHelper#unwrapCause(Throwable)
- */
- public Throwable unwrapCause() {
- return ExceptionsHelper.unwrapCause(this);
- }
- /**
- * Return the detail message, including the message from the nested exception
- * if there is one.
- */
- public String getDetailedMessage() {
- if (getCause() != null) {
- StringBuilder sb = new StringBuilder();
- sb.append(toString()).append("; ");
- if (getCause() instanceof ElasticsearchException) {
- sb.append(((ElasticsearchException) getCause()).getDetailedMessage());
- } else {
- sb.append(getCause());
- }
- return sb.toString();
- } else {
- return super.toString();
- }
- }
- /**
- * Retrieve the innermost cause of this exception, if none, returns the current exception.
- */
- public Throwable getRootCause() {
- Throwable rootCause = this;
- Throwable cause = getCause();
- while (cause != null && cause != rootCause) {
- rootCause = cause;
- cause = cause.getCause();
- }
- return rootCause;
- }
- @Override
- public void writeTo(StreamOutput out) throws IOException {
- out.writeOptionalString(this.getMessage());
- out.writeException(this.getCause());
- writeStackTraces(this, out, StreamOutput::writeException);
- out.writeMapOfLists(headers, StreamOutput::writeString, StreamOutput::writeString);
- out.writeMapOfLists(metadata, StreamOutput::writeString, StreamOutput::writeString);
- }
- public static ElasticsearchException readException(StreamInput input, int id) throws IOException {
- CheckedFunction<StreamInput, ? extends ElasticsearchException, IOException> elasticsearchException = ID_TO_SUPPLIER.get(id);
- if (elasticsearchException == null) {
- if (id == 127 && input.getVersion().before(Version.V_7_5_0)) {
- // was SearchContextException
- return new SearchException(input);
- }
- throw new IllegalStateException("unknown exception for id: " + id);
- }
- return elasticsearchException.apply(input);
- }
- /**
- * Returns <code>true</code> iff the given class is a registered for an exception to be read.
- */
- public static boolean isRegistered(Class<? extends Throwable> exception, Version version) {
- ElasticsearchExceptionHandle elasticsearchExceptionHandle = CLASS_TO_ELASTICSEARCH_EXCEPTION_HANDLE.get(exception);
- if (elasticsearchExceptionHandle != null) {
- return version.onOrAfter(elasticsearchExceptionHandle.versionAdded);
- }
- return false;
- }
- static Set<Class<? extends ElasticsearchException>> getRegisteredKeys() { // for testing
- return CLASS_TO_ELASTICSEARCH_EXCEPTION_HANDLE.keySet();
- }
- /**
- * Returns the serialization id the given exception.
- */
- public static int getId(Class<? extends ElasticsearchException> exception) {
- return CLASS_TO_ELASTICSEARCH_EXCEPTION_HANDLE.get(exception).id;
- }
- @Override
- public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
- Throwable ex = ExceptionsHelper.unwrapCause(this);
- if (ex != this) {
- generateThrowableXContent(builder, params, this);
- } else {
- innerToXContent(builder, params, this, getExceptionName(), getMessage(), headers, metadata, getCause());
- }
- return builder;
- }
- protected static void innerToXContent(XContentBuilder builder, Params params,
- Throwable throwable, String type, String message, Map<String, List<String>> headers,
- Map<String, List<String>> metadata, Throwable cause) throws IOException {
- builder.field(TYPE, type);
- builder.field(REASON, message);
- for (Map.Entry<String, List<String>> entry : metadata.entrySet()) {
- headerToXContent(builder, entry.getKey().substring("es.".length()), entry.getValue());
- }
- 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 (headers.isEmpty() == false) {
- builder.startObject(HEADER);
- for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
- headerToXContent(builder, entry.getKey(), entry.getValue());
- }
- builder.endObject();
- }
- if (params.paramAsBoolean(REST_EXCEPTION_SKIP_STACK_TRACE, REST_EXCEPTION_SKIP_STACK_TRACE_DEFAULT) == false) {
- builder.field(STACK_TRACE, ExceptionsHelper.stackTrace(throwable));
- }
- Throwable[] allSuppressed = throwable.getSuppressed();
- if (allSuppressed.length > 0) {
- builder.startArray(SUPPRESSED.getPreferredName());
- for (Throwable suppressed : allSuppressed) {
- builder.startObject();
- generateThrowableXContent(builder, params, suppressed);
- builder.endObject();
- }
- builder.endArray();
- }
- }
- private static void headerToXContent(XContentBuilder builder, String key, List<String> values) throws IOException {
- if (values != null && values.isEmpty() == false) {
- if (values.size() == 1) {
- builder.field(key, values.get(0));
- } else {
- builder.startArray(key);
- for (String value : values) {
- builder.value(value);
- }
- builder.endArray();
- }
- }
- }
- /**
- * Renders additional per exception information into the XContent
- */
- protected void metadataToXContent(XContentBuilder builder, Params params) throws IOException {
- }
- /**
- * Generate a {@link ElasticsearchException} from a {@link XContentParser}. This does not
- * return the original exception type (ie NodeClosedException for example) but just wraps
- * the type, the reason and the cause of the exception. It also recursively parses the
- * tree structure of the cause, returning it as a tree structure of {@link ElasticsearchException}
- * instances.
- */
- public static ElasticsearchException fromXContent(XContentParser parser) throws IOException {
- XContentParser.Token token = parser.nextToken();
- ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation);
- return innerFromXContent(parser, false);
- }
- public static ElasticsearchException innerFromXContent(XContentParser parser, boolean parseRootCauses) throws IOException {
- XContentParser.Token token = parser.currentToken();
- ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation);
- String type = null, reason = null, stack = null;
- ElasticsearchException cause = null;
- Map<String, List<String>> metadata = new HashMap<>();
- Map<String, List<String>> headers = new HashMap<>();
- List<ElasticsearchException> rootCauses = new ArrayList<>();
- List<ElasticsearchException> suppressed = new ArrayList<>();
- for (; token == XContentParser.Token.FIELD_NAME; token = parser.nextToken()) {
- String currentFieldName = parser.currentName();
- token = parser.nextToken();
- if (token.isValue()) {
- if (TYPE.equals(currentFieldName)) {
- type = parser.text();
- } else if (REASON.equals(currentFieldName)) {
- reason = parser.text();
- } else if (STACK_TRACE.equals(currentFieldName)) {
- stack = parser.text();
- } else if (token == XContentParser.Token.VALUE_STRING) {
- metadata.put(currentFieldName, Collections.singletonList(parser.text()));
- }
- } else if (token == XContentParser.Token.START_OBJECT) {
- if (CAUSED_BY.equals(currentFieldName)) {
- cause = fromXContent(parser);
- } else if (HEADER.equals(currentFieldName)) {
- while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
- if (token == XContentParser.Token.FIELD_NAME) {
- currentFieldName = parser.currentName();
- } else {
- List<String> values = headers.getOrDefault(currentFieldName, new ArrayList<>());
- if (token == XContentParser.Token.VALUE_STRING) {
- values.add(parser.text());
- } else if (token == XContentParser.Token.START_ARRAY) {
- while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
- if (token == XContentParser.Token.VALUE_STRING) {
- values.add(parser.text());
- } else {
- parser.skipChildren();
- }
- }
- } else if (token == XContentParser.Token.START_OBJECT) {
- parser.skipChildren();
- }
- headers.put(currentFieldName, values);
- }
- }
- } else {
- // Any additional metadata object added by the metadataToXContent method is ignored
- // and skipped, so that the parser does not fail on unknown fields. The parser only
- // support metadata key-pairs and metadata arrays of values.
- parser.skipChildren();
- }
- } else if (token == XContentParser.Token.START_ARRAY) {
- if (parseRootCauses && ROOT_CAUSE.equals(currentFieldName)) {
- while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
- rootCauses.add(fromXContent(parser));
- }
- } else if (SUPPRESSED.match(currentFieldName, parser.getDeprecationHandler())) {
- while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
- suppressed.add(fromXContent(parser));
- }
- } else {
- // Parse the array and add each item to the corresponding list of metadata.
- // Arrays of objects are not supported yet and just ignored and skipped.
- List<String> values = new ArrayList<>();
- while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
- if (token == XContentParser.Token.VALUE_STRING) {
- values.add(parser.text());
- } else {
- parser.skipChildren();
- }
- }
- if (values.size() > 0) {
- if (metadata.containsKey(currentFieldName)) {
- values.addAll(metadata.get(currentFieldName));
- }
- metadata.put(currentFieldName, values);
- }
- }
- }
- }
- ElasticsearchException e = new ElasticsearchException(buildMessage(type, reason, stack), cause);
- for (Map.Entry<String, List<String>> entry : metadata.entrySet()) {
- //subclasses can print out additional metadata through the metadataToXContent method. Simple key-value pairs will be
- //parsed back and become part of this metadata set, while objects and arrays are not supported when parsing back.
- //Those key-value pairs become part of the metadata set and inherit the "es." prefix as that is currently required
- //by addMetadata. The prefix will get stripped out when printing metadata out so it will be effectively invisible.
- //TODO move subclasses that print out simple metadata to using addMetadata directly and support also numbers and booleans.
- //TODO rename metadataToXContent and have only SearchPhaseExecutionException use it, which prints out complex objects
- e.addMetadata("es." + entry.getKey(), entry.getValue());
- }
- for (Map.Entry<String, List<String>> header : headers.entrySet()) {
- e.addHeader(header.getKey(), header.getValue());
- }
- // Adds root causes as suppressed exception. This way they are not lost
- // after parsing and can be retrieved using getSuppressed() method.
- for (ElasticsearchException rootCause : rootCauses) {
- e.addSuppressed(rootCause);
- }
- for (ElasticsearchException s : suppressed) {
- e.addSuppressed(s);
- }
- return e;
- }
- /**
- * 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, Map, Throwable)}.
- *
- * This method is usually used when the {@link Throwable} is rendered as a part of another XContent object, and its result can
- * be parsed back using the {@link #fromXContent(XContentParser)} method.
- */
- 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 {
- innerToXContent(builder, params, t, getExceptionName(t), t.getMessage(), emptyMap(), emptyMap(), t.getCause());
- }
- }
- /**
- * 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, and its output can be parsed
- * by the {@link #failureFromXContent(XContentParser)} method.
- */
- 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();
- rootCause.toXContent(builder, new DelegatingMapParams(singletonMap(REST_EXCEPTION_SKIP_CAUSE, "true"), params));
- builder.endObject();
- }
- builder.endArray();
- }
- generateThrowableXContent(builder, params, e);
- builder.endObject();
- }
- /**
- * Parses the output of {@link #generateFailureXContent(XContentBuilder, Params, Exception, boolean)}
- */
- public static ElasticsearchException failureFromXContent(XContentParser parser) throws IOException {
- XContentParser.Token token = parser.currentToken();
- ensureFieldName(parser, token, ERROR);
- token = parser.nextToken();
- if (token.isValue()) {
- return new ElasticsearchException(buildMessage("exception", parser.text(), null));
- }
- ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser::getTokenLocation);
- token = parser.nextToken();
- // Root causes are parsed in the innerFromXContent() and are added as suppressed exceptions.
- return innerFromXContent(parser, true);
- }
- /**
- * Returns the root cause of this exception or multiple if different shards caused different exceptions
- */
- public ElasticsearchException[] guessRootCauses() {
- final Throwable cause = getCause();
- if (cause != null && cause instanceof ElasticsearchException) {
- return ((ElasticsearchException) cause).guessRootCauses();
- }
- return new ElasticsearchException[]{this};
- }
- /**
- * Returns the root cause of this exception or multiple if different shards caused different exceptions.
- * If the given exception is not an instance of {@link org.elasticsearch.ElasticsearchException} an empty array
- * is returned.
- */
- public static ElasticsearchException[] guessRootCauses(Throwable t) {
- Throwable ex = ExceptionsHelper.unwrapCause(t);
- if (ex instanceof ElasticsearchException) {
- // ElasticsearchException knows how to guess its own root cause
- return ((ElasticsearchException) ex).guessRootCauses();
- }
- if (ex instanceof XContentParseException) {
- /*
- * We'd like to unwrap parsing exceptions to the inner-most
- * parsing exception because that is generally the most interesting
- * exception to return to the user. If that exception is caused by
- * an ElasticsearchException we'd like to keep unwrapping because
- * ElasticserachExceptions tend to contain useful information for
- * the user.
- */
- Throwable cause = ex.getCause();
- if (cause != null) {
- if (cause instanceof XContentParseException || cause instanceof ElasticsearchException) {
- return guessRootCauses(ex.getCause());
- }
- }
- }
- return new ElasticsearchException[]{new ElasticsearchException(ex.getMessage(), ex) {
- @Override
- protected String getExceptionName() {
- return getExceptionName(getCause());
- }
- }};
- }
- protected String getExceptionName() {
- return getExceptionName(this);
- }
- /**
- * Returns a underscore case name for the given exception. This method strips {@code Elasticsearch} prefixes from exception names.
- */
- public static String getExceptionName(Throwable ex) {
- String simpleName = ex.getClass().getSimpleName();
- if (simpleName.startsWith("Elasticsearch")) {
- simpleName = simpleName.substring("Elasticsearch".length());
- }
- // TODO: do we really need to make the exception name in underscore casing?
- return toUnderscoreCase(simpleName);
- }
- static String buildMessage(String type, String reason, String stack) {
- StringBuilder message = new StringBuilder("Elasticsearch exception [");
- message.append(TYPE).append('=').append(type).append(", ");
- message.append(REASON).append('=').append(reason);
- if (stack != null) {
- message.append(", ").append(STACK_TRACE).append('=').append(stack);
- }
- message.append(']');
- return message.toString();
- }
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- if (metadata.containsKey(INDEX_METADATA_KEY)) {
- builder.append(getIndex());
- if (metadata.containsKey(SHARD_METADATA_KEY)) {
- builder.append('[').append(getShardId()).append(']');
- }
- builder.append(' ');
- }
- return builder.append(super.toString().trim()).toString();
- }
- /**
- * Deserializes stacktrace elements as well as suppressed exceptions from the given output stream and
- * adds it to the given exception.
- */
- public static <T extends Throwable> T readStackTrace(T throwable, StreamInput in) throws IOException {
- final int stackTraceElements = in.readVInt();
- StackTraceElement[] stackTrace = new StackTraceElement[stackTraceElements];
- for (int i = 0; i < stackTraceElements; i++) {
- final String declaringClasss = in.readString();
- final String fileName = in.readOptionalString();
- final String methodName = in.readString();
- final int lineNumber = in.readVInt();
- stackTrace[i] = new StackTraceElement(declaringClasss, methodName, fileName, lineNumber);
- }
- throwable.setStackTrace(stackTrace);
- int numSuppressed = in.readVInt();
- for (int i = 0; i < numSuppressed; i++) {
- throwable.addSuppressed(in.readException());
- }
- return throwable;
- }
- /**
- * Serializes the given exceptions stacktrace elements as well as it's suppressed exceptions to the given output stream.
- */
- public static <T extends Throwable> T writeStackTraces(T throwable, StreamOutput out,
- Writer<Throwable> exceptionWriter) throws IOException {
- StackTraceElement[] stackTrace = throwable.getStackTrace();
- out.writeVInt(stackTrace.length);
- for (StackTraceElement element : stackTrace) {
- out.writeString(element.getClassName());
- out.writeOptionalString(element.getFileName());
- out.writeString(element.getMethodName());
- out.writeVInt(element.getLineNumber());
- }
- Throwable[] suppressed = throwable.getSuppressed();
- out.writeVInt(suppressed.length);
- for (Throwable t : suppressed) {
- exceptionWriter.write(out, t);
- }
- return throwable;
- }
- /**
- * This is the list of Exceptions Elasticsearch can throw over the wire or save into a corruption marker. Each value in the enum is a
- * single exception tying the Class to an id for use of the encode side and the id back to a constructor for use on the decode side. As
- * such its ok if the exceptions to change names so long as their constructor can still read the exception. Each exception is listed
- * in id order below. If you want to remove an exception leave a tombstone comment and mark the id as null in
- * ExceptionSerializationTests.testIds.ids.
- */
- private enum ElasticsearchExceptionHandle {
- INDEX_SHARD_SNAPSHOT_FAILED_EXCEPTION(org.elasticsearch.index.snapshots.IndexShardSnapshotFailedException.class,
- org.elasticsearch.index.snapshots.IndexShardSnapshotFailedException::new, 0, UNKNOWN_VERSION_ADDED),
- DFS_PHASE_EXECUTION_EXCEPTION(org.elasticsearch.search.dfs.DfsPhaseExecutionException.class,
- org.elasticsearch.search.dfs.DfsPhaseExecutionException::new, 1, UNKNOWN_VERSION_ADDED),
- EXECUTION_CANCELLED_EXCEPTION(org.elasticsearch.common.util.CancellableThreads.ExecutionCancelledException.class,
- org.elasticsearch.common.util.CancellableThreads.ExecutionCancelledException::new, 2, UNKNOWN_VERSION_ADDED),
- MASTER_NOT_DISCOVERED_EXCEPTION(org.elasticsearch.discovery.MasterNotDiscoveredException.class,
- org.elasticsearch.discovery.MasterNotDiscoveredException::new, 3, UNKNOWN_VERSION_ADDED),
- ELASTICSEARCH_SECURITY_EXCEPTION(org.elasticsearch.ElasticsearchSecurityException.class,
- org.elasticsearch.ElasticsearchSecurityException::new, 4, UNKNOWN_VERSION_ADDED),
- INDEX_SHARD_RESTORE_EXCEPTION(org.elasticsearch.index.snapshots.IndexShardRestoreException.class,
- org.elasticsearch.index.snapshots.IndexShardRestoreException::new, 5, UNKNOWN_VERSION_ADDED),
- INDEX_CLOSED_EXCEPTION(org.elasticsearch.indices.IndexClosedException.class,
- org.elasticsearch.indices.IndexClosedException::new, 6, UNKNOWN_VERSION_ADDED),
- BIND_HTTP_EXCEPTION(org.elasticsearch.http.BindHttpException.class,
- org.elasticsearch.http.BindHttpException::new, 7, UNKNOWN_VERSION_ADDED),
- REDUCE_SEARCH_PHASE_EXCEPTION(org.elasticsearch.action.search.ReduceSearchPhaseException.class,
- org.elasticsearch.action.search.ReduceSearchPhaseException::new, 8, UNKNOWN_VERSION_ADDED),
- NODE_CLOSED_EXCEPTION(org.elasticsearch.node.NodeClosedException.class,
- org.elasticsearch.node.NodeClosedException::new, 9, UNKNOWN_VERSION_ADDED),
- SNAPSHOT_FAILED_ENGINE_EXCEPTION(org.elasticsearch.index.engine.SnapshotFailedEngineException.class,
- org.elasticsearch.index.engine.SnapshotFailedEngineException::new, 10, UNKNOWN_VERSION_ADDED),
- SHARD_NOT_FOUND_EXCEPTION(org.elasticsearch.index.shard.ShardNotFoundException.class,
- org.elasticsearch.index.shard.ShardNotFoundException::new, 11, UNKNOWN_VERSION_ADDED),
- CONNECT_TRANSPORT_EXCEPTION(org.elasticsearch.transport.ConnectTransportException.class,
- org.elasticsearch.transport.ConnectTransportException::new, 12, UNKNOWN_VERSION_ADDED),
- NOT_SERIALIZABLE_TRANSPORT_EXCEPTION(org.elasticsearch.transport.NotSerializableTransportException.class,
- org.elasticsearch.transport.NotSerializableTransportException::new, 13, UNKNOWN_VERSION_ADDED),
- RESPONSE_HANDLER_FAILURE_TRANSPORT_EXCEPTION(org.elasticsearch.transport.ResponseHandlerFailureTransportException.class,
- org.elasticsearch.transport.ResponseHandlerFailureTransportException::new, 14, UNKNOWN_VERSION_ADDED),
- INDEX_CREATION_EXCEPTION(org.elasticsearch.indices.IndexCreationException.class,
- org.elasticsearch.indices.IndexCreationException::new, 15, UNKNOWN_VERSION_ADDED),
- INDEX_NOT_FOUND_EXCEPTION(org.elasticsearch.index.IndexNotFoundException.class,
- org.elasticsearch.index.IndexNotFoundException::new, 16, UNKNOWN_VERSION_ADDED),
- ILLEGAL_SHARD_ROUTING_STATE_EXCEPTION(org.elasticsearch.cluster.routing.IllegalShardRoutingStateException.class,
- org.elasticsearch.cluster.routing.IllegalShardRoutingStateException::new, 17, UNKNOWN_VERSION_ADDED),
- BROADCAST_SHARD_OPERATION_FAILED_EXCEPTION(org.elasticsearch.action.support.broadcast.BroadcastShardOperationFailedException.class,
- org.elasticsearch.action.support.broadcast.BroadcastShardOperationFailedException::new, 18, UNKNOWN_VERSION_ADDED),
- RESOURCE_NOT_FOUND_EXCEPTION(org.elasticsearch.ResourceNotFoundException.class,
- org.elasticsearch.ResourceNotFoundException::new, 19, UNKNOWN_VERSION_ADDED),
- ACTION_TRANSPORT_EXCEPTION(org.elasticsearch.transport.ActionTransportException.class,
- org.elasticsearch.transport.ActionTransportException::new, 20, UNKNOWN_VERSION_ADDED),
- ELASTICSEARCH_GENERATION_EXCEPTION(org.elasticsearch.ElasticsearchGenerationException.class,
- org.elasticsearch.ElasticsearchGenerationException::new, 21, UNKNOWN_VERSION_ADDED),
- // 22 was CreateFailedEngineException
- INDEX_SHARD_STARTED_EXCEPTION(org.elasticsearch.index.shard.IndexShardStartedException.class,
- org.elasticsearch.index.shard.IndexShardStartedException::new, 23, UNKNOWN_VERSION_ADDED),
- SEARCH_CONTEXT_MISSING_EXCEPTION(org.elasticsearch.search.SearchContextMissingException.class,
- org.elasticsearch.search.SearchContextMissingException::new, 24, UNKNOWN_VERSION_ADDED),
- GENERAL_SCRIPT_EXCEPTION(org.elasticsearch.script.GeneralScriptException.class,
- org.elasticsearch.script.GeneralScriptException::new, 25, UNKNOWN_VERSION_ADDED),
- // 26 was BatchOperationException
- SNAPSHOT_CREATION_EXCEPTION(org.elasticsearch.snapshots.SnapshotCreationException.class,
- org.elasticsearch.snapshots.SnapshotCreationException::new, 27, UNKNOWN_VERSION_ADDED),
- // 28 was DeleteFailedEngineException, deprecated in 6.0, removed in 7.0
- DOCUMENT_MISSING_EXCEPTION(org.elasticsearch.index.engine.DocumentMissingException.class,
- org.elasticsearch.index.engine.DocumentMissingException::new, 29, UNKNOWN_VERSION_ADDED),
- SNAPSHOT_EXCEPTION(org.elasticsearch.snapshots.SnapshotException.class,
- org.elasticsearch.snapshots.SnapshotException::new, 30, UNKNOWN_VERSION_ADDED),
- INVALID_ALIAS_NAME_EXCEPTION(org.elasticsearch.indices.InvalidAliasNameException.class,
- org.elasticsearch.indices.InvalidAliasNameException::new, 31, UNKNOWN_VERSION_ADDED),
- INVALID_INDEX_NAME_EXCEPTION(org.elasticsearch.indices.InvalidIndexNameException.class,
- org.elasticsearch.indices.InvalidIndexNameException::new, 32, UNKNOWN_VERSION_ADDED),
- INDEX_PRIMARY_SHARD_NOT_ALLOCATED_EXCEPTION(org.elasticsearch.indices.IndexPrimaryShardNotAllocatedException.class,
- org.elasticsearch.indices.IndexPrimaryShardNotAllocatedException::new, 33, UNKNOWN_VERSION_ADDED),
- TRANSPORT_EXCEPTION(org.elasticsearch.transport.TransportException.class,
- org.elasticsearch.transport.TransportException::new, 34, UNKNOWN_VERSION_ADDED),
- ELASTICSEARCH_PARSE_EXCEPTION(org.elasticsearch.ElasticsearchParseException.class,
- org.elasticsearch.ElasticsearchParseException::new, 35, UNKNOWN_VERSION_ADDED),
- SEARCH_EXCEPTION(org.elasticsearch.search.SearchException.class,
- org.elasticsearch.search.SearchException::new, 36, UNKNOWN_VERSION_ADDED),
- MAPPER_EXCEPTION(org.elasticsearch.index.mapper.MapperException.class,
- org.elasticsearch.index.mapper.MapperException::new, 37, UNKNOWN_VERSION_ADDED),
- INVALID_TYPE_NAME_EXCEPTION(org.elasticsearch.indices.InvalidTypeNameException.class,
- org.elasticsearch.indices.InvalidTypeNameException::new, 38, UNKNOWN_VERSION_ADDED),
- SNAPSHOT_RESTORE_EXCEPTION(org.elasticsearch.snapshots.SnapshotRestoreException.class,
- org.elasticsearch.snapshots.SnapshotRestoreException::new, 39, UNKNOWN_VERSION_ADDED),
- PARSING_EXCEPTION(org.elasticsearch.common.ParsingException.class, org.elasticsearch.common.ParsingException::new, 40,
- UNKNOWN_VERSION_ADDED),
- INDEX_SHARD_CLOSED_EXCEPTION(org.elasticsearch.index.shard.IndexShardClosedException.class,
- org.elasticsearch.index.shard.IndexShardClosedException::new, 41, UNKNOWN_VERSION_ADDED),
- RECOVER_FILES_RECOVERY_EXCEPTION(org.elasticsearch.indices.recovery.RecoverFilesRecoveryException.class,
- org.elasticsearch.indices.recovery.RecoverFilesRecoveryException::new, 42, UNKNOWN_VERSION_ADDED),
- TRUNCATED_TRANSLOG_EXCEPTION(org.elasticsearch.index.translog.TruncatedTranslogException.class,
- org.elasticsearch.index.translog.TruncatedTranslogException::new, 43, UNKNOWN_VERSION_ADDED),
- RECOVERY_FAILED_EXCEPTION(org.elasticsearch.indices.recovery.RecoveryFailedException.class,
- org.elasticsearch.indices.recovery.RecoveryFailedException::new, 44, UNKNOWN_VERSION_ADDED),
- INDEX_SHARD_RELOCATED_EXCEPTION(org.elasticsearch.index.shard.IndexShardRelocatedException.class,
- org.elasticsearch.index.shard.IndexShardRelocatedException::new, 45, UNKNOWN_VERSION_ADDED),
- NODE_SHOULD_NOT_CONNECT_EXCEPTION(org.elasticsearch.transport.NodeShouldNotConnectException.class,
- org.elasticsearch.transport.NodeShouldNotConnectException::new, 46, UNKNOWN_VERSION_ADDED),
- // 47 used to be for IndexTemplateAlreadyExistsException which was deprecated in 5.1 removed in 6.0
- TRANSLOG_CORRUPTED_EXCEPTION(org.elasticsearch.index.translog.TranslogCorruptedException.class,
- org.elasticsearch.index.translog.TranslogCorruptedException::new, 48, UNKNOWN_VERSION_ADDED),
- CLUSTER_BLOCK_EXCEPTION(org.elasticsearch.cluster.block.ClusterBlockException.class,
- org.elasticsearch.cluster.block.ClusterBlockException::new, 49, UNKNOWN_VERSION_ADDED),
- FETCH_PHASE_EXECUTION_EXCEPTION(org.elasticsearch.search.fetch.FetchPhaseExecutionException.class,
- org.elasticsearch.search.fetch.FetchPhaseExecutionException::new, 50, UNKNOWN_VERSION_ADDED),
- // 51 used to be for IndexShardAlreadyExistsException which was deprecated in 5.1 removed in 6.0
- VERSION_CONFLICT_ENGINE_EXCEPTION(org.elasticsearch.index.engine.VersionConflictEngineException.class,
- org.elasticsearch.index.engine.VersionConflictEngineException::new, 52, UNKNOWN_VERSION_ADDED),
- ENGINE_EXCEPTION(org.elasticsearch.index.engine.EngineException.class, org.elasticsearch.index.engine.EngineException::new, 53,
- UNKNOWN_VERSION_ADDED),
- // 54 was DocumentAlreadyExistsException, which is superseded by VersionConflictEngineException
- NO_SUCH_NODE_EXCEPTION(org.elasticsearch.action.NoSuchNodeException.class, org.elasticsearch.action.NoSuchNodeException::new, 55,
- UNKNOWN_VERSION_ADDED),
- SETTINGS_EXCEPTION(org.elasticsearch.common.settings.SettingsException.class,
- org.elasticsearch.common.settings.SettingsException::new, 56, UNKNOWN_VERSION_ADDED),
- INDEX_TEMPLATE_MISSING_EXCEPTION(org.elasticsearch.indices.IndexTemplateMissingException.class,
- org.elasticsearch.indices.IndexTemplateMissingException::new, 57, UNKNOWN_VERSION_ADDED),
- SEND_REQUEST_TRANSPORT_EXCEPTION(org.elasticsearch.transport.SendRequestTransportException.class,
- org.elasticsearch.transport.SendRequestTransportException::new, 58, UNKNOWN_VERSION_ADDED),
- // 59 used to be EsRejectedExecutionException
- // 60 used to be for EarlyTerminationException
- // 61 used to be for RoutingValidationException
- NOT_SERIALIZABLE_EXCEPTION_WRAPPER(org.elasticsearch.common.io.stream.NotSerializableExceptionWrapper.class,
- org.elasticsearch.common.io.stream.NotSerializableExceptionWrapper::new, 62, UNKNOWN_VERSION_ADDED),
- ALIAS_FILTER_PARSING_EXCEPTION(org.elasticsearch.indices.AliasFilterParsingException.class,
- org.elasticsearch.indices.AliasFilterParsingException::new, 63, UNKNOWN_VERSION_ADDED),
- // 64 was DeleteByQueryFailedEngineException, which was removed in 5.0
- GATEWAY_EXCEPTION(org.elasticsearch.gateway.GatewayException.class, org.elasticsearch.gateway.GatewayException::new, 65,
- UNKNOWN_VERSION_ADDED),
- INDEX_SHARD_NOT_RECOVERING_EXCEPTION(org.elasticsearch.index.shard.IndexShardNotRecoveringException.class,
- org.elasticsearch.index.shard.IndexShardNotRecoveringException::new, 66, UNKNOWN_VERSION_ADDED),
- HTTP_EXCEPTION(org.elasticsearch.http.HttpException.class, org.elasticsearch.http.HttpException::new, 67, UNKNOWN_VERSION_ADDED),
- ELASTICSEARCH_EXCEPTION(org.elasticsearch.ElasticsearchException.class,
- org.elasticsearch.ElasticsearchException::new, 68, UNKNOWN_VERSION_ADDED),
- SNAPSHOT_MISSING_EXCEPTION(org.elasticsearch.snapshots.SnapshotMissingException.class,
- org.elasticsearch.snapshots.SnapshotMissingException::new, 69, UNKNOWN_VERSION_ADDED),
- PRIMARY_MISSING_ACTION_EXCEPTION(org.elasticsearch.action.PrimaryMissingActionException.class,
- org.elasticsearch.action.PrimaryMissingActionException::new, 70, UNKNOWN_VERSION_ADDED),
- FAILED_NODE_EXCEPTION(org.elasticsearch.action.FailedNodeException.class, org.elasticsearch.action.FailedNodeException::new, 71,
- UNKNOWN_VERSION_ADDED),
- SEARCH_PARSE_EXCEPTION(org.elasticsearch.search.SearchParseException.class, org.elasticsearch.search.SearchParseException::new, 72,
- UNKNOWN_VERSION_ADDED),
- CONCURRENT_SNAPSHOT_EXECUTION_EXCEPTION(org.elasticsearch.snapshots.ConcurrentSnapshotExecutionException.class,
- org.elasticsearch.snapshots.ConcurrentSnapshotExecutionException::new, 73, UNKNOWN_VERSION_ADDED),
- BLOB_STORE_EXCEPTION(org.elasticsearch.common.blobstore.BlobStoreException.class,
- org.elasticsearch.common.blobstore.BlobStoreException::new, 74, UNKNOWN_VERSION_ADDED),
- INCOMPATIBLE_CLUSTER_STATE_VERSION_EXCEPTION(org.elasticsearch.cluster.IncompatibleClusterStateVersionException.class,
- org.elasticsearch.cluster.IncompatibleClusterStateVersionException::new, 75, UNKNOWN_VERSION_ADDED),
- RECOVERY_ENGINE_EXCEPTION(org.elasticsearch.index.engine.RecoveryEngineException.class,
- org.elasticsearch.index.engine.RecoveryEngineException::new, 76, UNKNOWN_VERSION_ADDED),
- UNCATEGORIZED_EXECUTION_EXCEPTION(org.elasticsearch.common.util.concurrent.UncategorizedExecutionException.class,
- org.elasticsearch.common.util.concurrent.UncategorizedExecutionException::new, 77, UNKNOWN_VERSION_ADDED),
- TIMESTAMP_PARSING_EXCEPTION(org.elasticsearch.action.TimestampParsingException.class,
- org.elasticsearch.action.TimestampParsingException::new, 78, UNKNOWN_VERSION_ADDED),
- ROUTING_MISSING_EXCEPTION(org.elasticsearch.action.RoutingMissingException.class,
- org.elasticsearch.action.RoutingMissingException::new, 79, UNKNOWN_VERSION_ADDED),
- // 80 was IndexFailedEngineException, deprecated in 6.0, removed in 7.0
- INDEX_SHARD_RESTORE_FAILED_EXCEPTION(org.elasticsearch.index.snapshots.IndexShardRestoreFailedException.class,
- org.elasticsearch.index.snapshots.IndexShardRestoreFailedException::new, 81, UNKNOWN_VERSION_ADDED),
- REPOSITORY_EXCEPTION(org.elasticsearch.repositories.RepositoryException.class,
- org.elasticsearch.repositories.RepositoryException::new, 82, UNKNOWN_VERSION_ADDED),
- RECEIVE_TIMEOUT_TRANSPORT_EXCEPTION(org.elasticsearch.transport.ReceiveTimeoutTransportException.class,
- org.elasticsearch.transport.ReceiveTimeoutTransportException::new, 83, UNKNOWN_VERSION_ADDED),
- NODE_DISCONNECTED_EXCEPTION(org.elasticsearch.transport.NodeDisconnectedException.class,
- org.elasticsearch.transport.NodeDisconnectedException::new, 84, UNKNOWN_VERSION_ADDED),
- // 85 used to be for AlreadyExpiredException
- AGGREGATION_EXECUTION_EXCEPTION(org.elasticsearch.search.aggregations.AggregationExecutionException.class,
- org.elasticsearch.search.aggregations.AggregationExecutionException::new, 86, UNKNOWN_VERSION_ADDED),
- // 87 used to be for MergeMappingException
- INVALID_INDEX_TEMPLATE_EXCEPTION(org.elasticsearch.indices.InvalidIndexTemplateException.class,
- org.elasticsearch.indices.InvalidIndexTemplateException::new, 88, UNKNOWN_VERSION_ADDED),
- REFRESH_FAILED_ENGINE_EXCEPTION(org.elasticsearch.index.engine.RefreshFailedEngineException.class,
- org.elasticsearch.index.engine.RefreshFailedEngineException::new, 90, UNKNOWN_VERSION_ADDED),
- AGGREGATION_INITIALIZATION_EXCEPTION(org.elasticsearch.search.aggregations.AggregationInitializationException.class,
- org.elasticsearch.search.aggregations.AggregationInitializationException::new, 91, UNKNOWN_VERSION_ADDED),
- DELAY_RECOVERY_EXCEPTION(org.elasticsearch.indices.recovery.DelayRecoveryException.class,
- org.elasticsearch.indices.recovery.DelayRecoveryException::new, 92, UNKNOWN_VERSION_ADDED),
- // 93 used to be for IndexWarmerMissingException
- NO_NODE_AVAILABLE_EXCEPTION(org.elasticsearch.client.transport.NoNodeAvailableException.class,
- org.elasticsearch.client.transport.NoNodeAvailableException::new, 94, UNKNOWN_VERSION_ADDED),
- INVALID_SNAPSHOT_NAME_EXCEPTION(org.elasticsearch.snapshots.InvalidSnapshotNameException.class,
- org.elasticsearch.snapshots.InvalidSnapshotNameException::new, 96, UNKNOWN_VERSION_ADDED),
- ILLEGAL_INDEX_SHARD_STATE_EXCEPTION(org.elasticsearch.index.shard.IllegalIndexShardStateException.class,
- org.elasticsearch.index.shard.IllegalIndexShardStateException::new, 97, UNKNOWN_VERSION_ADDED),
- INDEX_SHARD_SNAPSHOT_EXCEPTION(org.elasticsearch.index.snapshots.IndexShardSnapshotException.class,
- org.elasticsearch.index.snapshots.IndexShardSnapshotException::new, 98, UNKNOWN_VERSION_ADDED),
- INDEX_SHARD_NOT_STARTED_EXCEPTION(org.elasticsearch.index.shard.IndexShardNotStartedException.class,
- org.elasticsearch.index.shard.IndexShardNotStartedException::new, 99, UNKNOWN_VERSION_ADDED),
- SEARCH_PHASE_EXECUTION_EXCEPTION(org.elasticsearch.action.search.SearchPhaseExecutionException.class,
- org.elasticsearch.action.search.SearchPhaseExecutionException::new, 100, UNKNOWN_VERSION_ADDED),
- ACTION_NOT_FOUND_TRANSPORT_EXCEPTION(org.elasticsearch.transport.ActionNotFoundTransportException.class,
- org.elasticsearch.transport.ActionNotFoundTransportException::new, 101, UNKNOWN_VERSION_ADDED),
- TRANSPORT_SERIALIZATION_EXCEPTION(org.elasticsearch.transport.TransportSerializationException.class,
- org.elasticsearch.transport.TransportSerializationException::new, 102, UNKNOWN_VERSION_ADDED),
- REMOTE_TRANSPORT_EXCEPTION(org.elasticsearch.transport.RemoteTransportException.class,
- org.elasticsearch.transport.RemoteTransportException::new, 103, UNKNOWN_VERSION_ADDED),
- ENGINE_CREATION_FAILURE_EXCEPTION(org.elasticsearch.index.engine.EngineCreationFailureException.class,
- org.elasticsearch.index.engine.EngineCreationFailureException::new, 104, UNKNOWN_VERSION_ADDED),
- ROUTING_EXCEPTION(org.elasticsearch.cluster.routing.RoutingException.class,
- org.elasticsearch.cluster.routing.RoutingException::new, 105, UNKNOWN_VERSION_ADDED),
- INDEX_SHARD_RECOVERY_EXCEPTION(org.elasticsearch.index.shard.IndexShardRecoveryException.class,
- org.elasticsearch.index.shard.IndexShardRecoveryException::new, 106, UNKNOWN_VERSION_ADDED),
- REPOSITORY_MISSING_EXCEPTION(org.elasticsearch.repositories.RepositoryMissingException.class,
- org.elasticsearch.repositories.RepositoryMissingException::new, 107, UNKNOWN_VERSION_ADDED),
- DOCUMENT_SOURCE_MISSING_EXCEPTION(org.elasticsearch.index.engine.DocumentSourceMissingException.class,
- org.elasticsearch.index.engine.DocumentSourceMissingException::new, 109, UNKNOWN_VERSION_ADDED),
- // 110 used to be FlushNotAllowedEngineException
- NO_CLASS_SETTINGS_EXCEPTION(org.elasticsearch.common.settings.NoClassSettingsException.class,
- org.elasticsearch.common.settings.NoClassSettingsException::new, 111, UNKNOWN_VERSION_ADDED),
- BIND_TRANSPORT_EXCEPTION(org.elasticsearch.transport.BindTransportException.class,
- org.elasticsearch.transport.BindTransportException::new, 112, UNKNOWN_VERSION_ADDED),
- ALIASES_NOT_FOUND_EXCEPTION(org.elasticsearch.rest.action.admin.indices.AliasesNotFoundException.class,
- org.elasticsearch.rest.action.admin.indices.AliasesNotFoundException::new, 113, UNKNOWN_VERSION_ADDED),
- INDEX_SHARD_RECOVERING_EXCEPTION(org.elasticsearch.index.shard.IndexShardRecoveringException.class,
- org.elasticsearch.index.shard.IndexShardRecoveringException::new, 114, UNKNOWN_VERSION_ADDED),
- TRANSLOG_EXCEPTION(org.elasticsearch.index.translog.TranslogException.class,
- org.elasticsearch.index.translog.TranslogException::new, 115, UNKNOWN_VERSION_ADDED),
- PROCESS_CLUSTER_EVENT_TIMEOUT_EXCEPTION(org.elasticsearch.cluster.metadata.ProcessClusterEventTimeoutException.class,
- org.elasticsearch.cluster.metadata.ProcessClusterEventTimeoutException::new, 116, UNKNOWN_VERSION_ADDED),
- RETRY_ON_PRIMARY_EXCEPTION(ReplicationOperation.RetryOnPrimaryException.class,
- ReplicationOperation.RetryOnPrimaryException::new, 117, UNKNOWN_VERSION_ADDED),
- ELASTICSEARCH_TIMEOUT_EXCEPTION(org.elasticsearch.ElasticsearchTimeoutException.class,
- org.elasticsearch.ElasticsearchTimeoutException::new, 118, UNKNOWN_VERSION_ADDED),
- QUERY_PHASE_EXECUTION_EXCEPTION(org.elasticsearch.search.query.QueryPhaseExecutionException.class,
- org.elasticsearch.search.query.QueryPhaseExecutionException::new, 119, UNKNOWN_VERSION_ADDED),
- REPOSITORY_VERIFICATION_EXCEPTION(org.elasticsearch.repositories.RepositoryVerificationException.class,
- org.elasticsearch.repositories.RepositoryVerificationException::new, 120, UNKNOWN_VERSION_ADDED),
- INVALID_AGGREGATION_PATH_EXCEPTION(org.elasticsearch.search.aggregations.InvalidAggregationPathException.class,
- org.elasticsearch.search.aggregations.InvalidAggregationPathException::new, 121, UNKNOWN_VERSION_ADDED),
- // 123 used to be IndexAlreadyExistsException and was renamed
- RESOURCE_ALREADY_EXISTS_EXCEPTION(ResourceAlreadyExistsException.class,
- ResourceAlreadyExistsException::new, 123, UNKNOWN_VERSION_ADDED),
- // 124 used to be Script.ScriptParseException
- HTTP_REQUEST_ON_TRANSPORT_EXCEPTION(TcpTransport.HttpRequestOnTransportException.class,
- TcpTransport.HttpRequestOnTransportException::new, 125, UNKNOWN_VERSION_ADDED),
- MAPPER_PARSING_EXCEPTION(org.elasticsearch.index.mapper.MapperParsingException.class,
- org.elasticsearch.index.mapper.MapperParsingException::new, 126, UNKNOWN_VERSION_ADDED),
- // 127 used to be org.elasticsearch.search.SearchContextException
- SEARCH_SOURCE_BUILDER_EXCEPTION(org.elasticsearch.search.builder.SearchSourceBuilderException.class,
- org.elasticsearch.search.builder.SearchSourceBuilderException::new, 128, UNKNOWN_VERSION_ADDED),
- // 129 was EngineClosedException
- NO_SHARD_AVAILABLE_ACTION_EXCEPTION(org.elasticsearch.action.NoShardAvailableActionException.class,
- org.elasticsearch.action.NoShardAvailableActionException::new, 130, UNKNOWN_VERSION_ADDED),
- UNAVAILABLE_SHARDS_EXCEPTION(org.elasticsearch.action.UnavailableShardsException.class,
- org.elasticsearch.action.UnavailableShardsException::new, 131, UNKNOWN_VERSION_ADDED),
- FLUSH_FAILED_ENGINE_EXCEPTION(org.elasticsearch.index.engine.FlushFailedEngineException.class,
- org.elasticsearch.index.engine.FlushFailedEngineException::new, 132, UNKNOWN_VERSION_ADDED),
- CIRCUIT_BREAKING_EXCEPTION(org.elasticsearch.common.breaker.CircuitBreakingException.class,
- org.elasticsearch.common.breaker.CircuitBreakingException::new, 133, UNKNOWN_VERSION_ADDED),
- NODE_NOT_CONNECTED_EXCEPTION(org.elasticsearch.transport.NodeNotConnectedException.class,
- org.elasticsearch.transport.NodeNotConnectedException::new, 134, UNKNOWN_VERSION_ADDED),
- STRICT_DYNAMIC_MAPPING_EXCEPTION(org.elasticsearch.index.mapper.StrictDynamicMappingException.class,
- org.elasticsearch.index.mapper.StrictDynamicMappingException::new, 135, UNKNOWN_VERSION_ADDED),
- RETRY_ON_REPLICA_EXCEPTION(org.elasticsearch.action.support.replication.TransportReplicationAction.RetryOnReplicaException.class,
- org.elasticsearch.action.support.replication.TransportReplicationAction.RetryOnReplicaException::new, 136,
- UNKNOWN_VERSION_ADDED),
- TYPE_MISSING_EXCEPTION(org.elasticsearch.indices.TypeMissingException.class,
- org.elasticsearch.indices.TypeMissingException::new, 137, UNKNOWN_VERSION_ADDED),
- FAILED_TO_COMMIT_CLUSTER_STATE_EXCEPTION(org.elasticsearch.cluster.coordination.FailedToCommitClusterStateException.class,
- org.elasticsearch.cluster.coordination.FailedToCommitClusterStateException::new, 140, UNKNOWN_VERSION_ADDED),
- QUERY_SHARD_EXCEPTION(org.elasticsearch.index.query.QueryShardException.class,
- org.elasticsearch.index.query.QueryShardException::new, 141, UNKNOWN_VERSION_ADDED),
- NO_LONGER_PRIMARY_SHARD_EXCEPTION(ShardStateAction.NoLongerPrimaryShardException.class,
- ShardStateAction.NoLongerPrimaryShardException::new, 142, UNKNOWN_VERSION_ADDED),
- SCRIPT_EXCEPTION(org.elasticsearch.script.ScriptException.class, org.elasticsearch.script.ScriptException::new, 143,
- UNKNOWN_VERSION_ADDED),
- NOT_MASTER_EXCEPTION(org.elasticsearch.cluster.NotMasterException.class, org.elasticsearch.cluster.NotMasterException::new, 144,
- UNKNOWN_VERSION_ADDED),
- STATUS_EXCEPTION(org.elasticsearch.ElasticsearchStatusException.class, org.elasticsearch.ElasticsearchStatusException::new, 145,
- UNKNOWN_VERSION_ADDED),
- TASK_CANCELLED_EXCEPTION(org.elasticsearch.tasks.TaskCancelledException.class,
- org.elasticsearch.tasks.TaskCancelledException::new, 146, UNKNOWN_VERSION_ADDED),
- SHARD_LOCK_OBTAIN_FAILED_EXCEPTION(org.elasticsearch.env.ShardLockObtainFailedException.class,
- org.elasticsearch.env.ShardLockObtainFailedException::new, 147, UNKNOWN_VERSION_ADDED),
- // 148 was UnknownNamedObjectException
- TOO_MANY_BUCKETS_EXCEPTION(MultiBucketConsumerService.TooManyBucketsException.class,
- MultiBucketConsumerService.TooManyBucketsException::new, 149, UNKNOWN_VERSION_ADDED),
- COORDINATION_STATE_REJECTED_EXCEPTION(org.elasticsearch.cluster.coordination.CoordinationStateRejectedException.class,
- org.elasticsearch.cluster.coordination.CoordinationStateRejectedException::new, 150, Version.V_7_0_0),
- SNAPSHOT_IN_PROGRESS_EXCEPTION(org.elasticsearch.snapshots.SnapshotInProgressException.class,
- org.elasticsearch.snapshots.SnapshotInProgressException::new, 151, UNKNOWN_VERSION_ADDED),
- NO_SUCH_REMOTE_CLUSTER_EXCEPTION(org.elasticsearch.transport.NoSuchRemoteClusterException.class,
- org.elasticsearch.transport.NoSuchRemoteClusterException::new, 152, UNKNOWN_VERSION_ADDED),
- RETENTION_LEASE_ALREADY_EXISTS_EXCEPTION(
- org.elasticsearch.index.seqno.RetentionLeaseAlreadyExistsException.class,
- org.elasticsearch.index.seqno.RetentionLeaseAlreadyExistsException::new,
- 153,
- UNKNOWN_VERSION_ADDED),
- RETENTION_LEASE_NOT_FOUND_EXCEPTION(
- org.elasticsearch.index.seqno.RetentionLeaseNotFoundException.class,
- org.elasticsearch.index.seqno.RetentionLeaseNotFoundException::new,
- 154,
- UNKNOWN_VERSION_ADDED),
- SHARD_NOT_IN_PRIMARY_MODE_EXCEPTION(
- org.elasticsearch.index.shard.ShardNotInPrimaryModeException.class,
- org.elasticsearch.index.shard.ShardNotInPrimaryModeException::new,
- 155,
- UNKNOWN_VERSION_ADDED),
- RETENTION_LEASE_INVALID_RETAINING_SEQUENCE_NUMBER_EXCEPTION(
- org.elasticsearch.index.seqno.RetentionLeaseInvalidRetainingSeqNoException.class,
- org.elasticsearch.index.seqno.RetentionLeaseInvalidRetainingSeqNoException::new,
- 156,
- Version.V_7_5_0),
- INGEST_PROCESSOR_EXCEPTION(
- org.elasticsearch.ingest.IngestProcessorException.class,
- org.elasticsearch.ingest.IngestProcessorException::new,
- 157,
- Version.V_7_5_0),
- PEER_RECOVERY_NOT_FOUND_EXCEPTION(
- org.elasticsearch.indices.recovery.PeerRecoveryNotFound.class,
- org.elasticsearch.indices.recovery.PeerRecoveryNotFound::new,
- 158,
- Version.V_7_9_0);
- final Class<? extends ElasticsearchException> exceptionClass;
- final CheckedFunction<StreamInput, ? extends ElasticsearchException, IOException> constructor;
- final int id;
- final Version versionAdded;
- <E extends ElasticsearchException> ElasticsearchExceptionHandle(Class<E> exceptionClass,
- CheckedFunction<StreamInput, E, IOException> constructor, int id,
- Version versionAdded) {
- // We need the exceptionClass because you can't dig it out of the constructor reliably.
- this.exceptionClass = exceptionClass;
- this.constructor = constructor;
- this.versionAdded = versionAdded;
- this.id = id;
- }
- }
- /**
- * Returns an array of all registered handle IDs. These are the IDs for every registered
- * exception.
- *
- * @return an array of all registered handle IDs
- */
- static int[] ids() {
- return Arrays.stream(ElasticsearchExceptionHandle.values()).mapToInt(h -> h.id).toArray();
- }
- /**
- * Returns an array of all registered pairs of handle IDs and exception classes. These pairs are
- * provided for every registered exception.
- *
- * @return an array of all registered pairs of handle IDs and exception classes
- */
- static Tuple<Integer, Class<? extends ElasticsearchException>>[] classes() {
- @SuppressWarnings("unchecked")
- final Tuple<Integer, Class<? extends ElasticsearchException>>[] ts =
- Arrays.stream(ElasticsearchExceptionHandle.values())
- .map(h -> Tuple.tuple(h.id, h.exceptionClass)).toArray(Tuple[]::new);
- return ts;
- }
- static {
- ID_TO_SUPPLIER = unmodifiableMap(Arrays
- .stream(ElasticsearchExceptionHandle.values()).collect(Collectors.toMap(e -> e.id, e -> e.constructor)));
- CLASS_TO_ELASTICSEARCH_EXCEPTION_HANDLE = unmodifiableMap(Arrays
- .stream(ElasticsearchExceptionHandle.values()).collect(Collectors.toMap(e -> e.exceptionClass, e -> e)));
- }
- public Index getIndex() {
- List<String> index = getMetadata(INDEX_METADATA_KEY);
- if (index != null && index.isEmpty() == false) {
- List<String> index_uuid = getMetadata(INDEX_METADATA_KEY_UUID);
- return new Index(index.get(0), index_uuid.get(0));
- }
- return null;
- }
- public ShardId getShardId() {
- List<String> shard = getMetadata(SHARD_METADATA_KEY);
- if (shard != null && shard.isEmpty() == false) {
- return new ShardId(getIndex(), Integer.parseInt(shard.get(0)));
- }
- return null;
- }
- public void setIndex(Index index) {
- if (index != null) {
- addMetadata(INDEX_METADATA_KEY, index.getName());
- addMetadata(INDEX_METADATA_KEY_UUID, index.getUUID());
- }
- }
- public void setIndex(String index) {
- if (index != null) {
- setIndex(new Index(index, INDEX_UUID_NA_VALUE));
- }
- }
- public void setShard(ShardId shardId) {
- if (shardId != null) {
- setIndex(shardId.getIndex());
- addMetadata(SHARD_METADATA_KEY, Integer.toString(shardId.id()));
- }
- }
- public void setResources(String type, String... id) {
- assert type != null;
- addMetadata(RESOURCE_METADATA_ID_KEY, id);
- addMetadata(RESOURCE_METADATA_TYPE_KEY, type);
- }
- public List<String> getResourceId() {
- return getMetadata(RESOURCE_METADATA_ID_KEY);
- }
- public String getResourceType() {
- List<String> header = getMetadata(RESOURCE_METADATA_TYPE_KEY);
- if (header != null && header.isEmpty() == false) {
- assert header.size() == 1;
- return header.get(0);
- }
- return null;
- }
- // lower cases and adds underscores to transitions in a name
- private static String toUnderscoreCase(String value) {
- StringBuilder sb = new StringBuilder();
- boolean changed = false;
- for (int i = 0; i < value.length(); i++) {
- char c = value.charAt(i);
- if (Character.isUpperCase(c)) {
- if (!changed) {
- // copy it over here
- for (int j = 0; j < i; j++) {
- sb.append(value.charAt(j));
- }
- changed = true;
- if (i == 0) {
- sb.append(Character.toLowerCase(c));
- } else {
- sb.append('_');
- sb.append(Character.toLowerCase(c));
- }
- } else {
- sb.append('_');
- sb.append(Character.toLowerCase(c));
- }
- } else {
- if (changed) {
- sb.append(c);
- }
- }
- }
- if (!changed) {
- return value;
- }
- return sb.toString();
- }
- }
|