Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generify Index and Shard exceptions #12023

Merged
merged 1 commit into from
Jul 14, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 116 additions & 8 deletions core/src/main/java/org/elasticsearch/ElasticsearchException.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@
import org.elasticsearch.common.logging.support.LoggerMessageFormat;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.index.shard.ShardNotFoundException;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.action.admin.indices.alias.delete.AliasesNotFoundException;

import java.io.IOException;
import java.lang.reflect.Constructor;
Expand All @@ -39,6 +44,11 @@
public class ElasticsearchException extends RuntimeException implements ToXContent {

public static final String REST_EXCEPTION_SKIP_CAUSE = "rest.exception.skip_cause";
private static final String INDEX_HEADER_KEY = "es.index";
private static final String SHARD_HEADER_KEY = "es.shard";
private static final String RESOURCE_HEADER_TYPE_KEY = "es.resource.type";
private static final String RESOURCE_HEADER_ID_KEY = "es.resource.id";

private static final Map<String, Constructor<? extends ElasticsearchException>> MAPPING;
private final Map<String, List<String>> headers = new HashMap<>();

Expand Down Expand Up @@ -252,7 +262,14 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
} else {
builder.field("type", getExceptionName());
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);
}
return builder;
}
Expand All @@ -277,6 +294,38 @@ protected final void causeToXContent(XContentBuilder builder, Params params) thr
}
}

protected final void renderHeader(XContentBuilder builder, Params params) throws IOException {
boolean hasHeader = false;
for (String key : headers.keySet()) {
if (key.startsWith("es.")) {
continue;
}
if (hasHeader == false) {
builder.startObject("header");
hasHeader = true;
}
List<String> values = headers.get(key);
xContentHeader(builder, key, values);
}
if (hasHeader) {
builder.endObject();
}
}

private void xContentHeader(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();
}
}
}

/**
* Statis toXContent helper method that also renders non {@link org.elasticsearch.ElasticsearchException} instances as XContent.
*/
Expand Down Expand Up @@ -342,7 +391,15 @@ public static String getExceptionName(Throwable ex) {

@Override
public String toString() {
return ExceptionsHelper.detailedMessage(this).trim();
StringBuilder builder = new StringBuilder();
if (headers.containsKey(INDEX_HEADER_KEY)) {
builder.append('[').append(getIndex()).append(']');
if (headers.containsKey(SHARD_HEADER_KEY)) {
builder.append('[').append(getShardId()).append(']');
}
builder.append(' ');
}
return builder.append(ExceptionsHelper.detailedMessage(this).trim()).toString();
}

/**
Expand Down Expand Up @@ -396,7 +453,6 @@ public static <T extends Throwable> T writeStackTraces(T throwable, StreamOutput
org.elasticsearch.indices.recovery.RecoverFilesRecoveryException.class,
org.elasticsearch.index.translog.TruncatedTranslogException.class,
org.elasticsearch.repositories.RepositoryException.class,
org.elasticsearch.index.shard.IndexShardException.class,
org.elasticsearch.index.engine.DocumentSourceMissingException.class,
org.elasticsearch.index.engine.DocumentMissingException.class,
org.elasticsearch.common.util.concurrent.EsRejectedExecutionException.class,
Expand All @@ -421,12 +477,10 @@ public static <T extends Throwable> T writeStackTraces(T throwable, StreamOutput
org.elasticsearch.index.snapshots.IndexShardSnapshotException.class,
org.elasticsearch.search.query.QueryPhaseExecutionException.class,
org.elasticsearch.cluster.metadata.ProcessClusterEventTimeoutException.class,
org.elasticsearch.index.shard.IndexShardCreationException.class,
org.elasticsearch.index.percolator.PercolatorException.class,
org.elasticsearch.snapshots.ConcurrentSnapshotExecutionException.class,
org.elasticsearch.indices.IndexTemplateAlreadyExistsException.class,
org.elasticsearch.indices.InvalidIndexNameException.class,
org.elasticsearch.index.IndexException.class,
org.elasticsearch.indices.recovery.DelayRecoveryException.class,
org.elasticsearch.indices.AliasFilterParsingException.class,
org.elasticsearch.indices.InvalidIndexTemplateException.class,
Expand All @@ -443,7 +497,6 @@ public static <T extends Throwable> T writeStackTraces(T throwable, StreamOutput
org.elasticsearch.cluster.block.ClusterBlockException.class,
org.elasticsearch.action.FailedNodeException.class,
org.elasticsearch.indices.TypeMissingException.class,
org.elasticsearch.index.IndexShardMissingException.class,
org.elasticsearch.indices.InvalidTypeNameException.class,
org.elasticsearch.transport.netty.SizeHeaderFrameDecoder.HttpOnTransportException.class,
org.elasticsearch.common.util.CancellableThreads.ExecutionCancelledException.class,
Expand Down Expand Up @@ -493,7 +546,6 @@ public static <T extends Throwable> T writeStackTraces(T throwable, StreamOutput
org.elasticsearch.ElasticsearchTimeoutException.class,
org.elasticsearch.search.SearchContextMissingException.class,
org.elasticsearch.transport.SendRequestTransportException.class,
org.elasticsearch.indices.IndexMissingException.class,
org.elasticsearch.index.IndexShardAlreadyExistsException.class,
org.elasticsearch.indices.IndexAlreadyExistsException.class,
org.elasticsearch.index.engine.DocumentAlreadyExistsException.class,
Expand All @@ -504,7 +556,7 @@ public static <T extends Throwable> T writeStackTraces(T throwable, StreamOutput
org.elasticsearch.index.shard.IndexShardNotStartedException.class,
org.elasticsearch.index.mapper.StrictDynamicMappingException.class,
org.elasticsearch.index.engine.EngineClosedException.class,
org.elasticsearch.rest.action.admin.indices.alias.delete.AliasesMissingException.class,
AliasesNotFoundException.class,
org.elasticsearch.transport.ResponseHandlerFailureTransportException.class,
org.elasticsearch.search.SearchParseException.class,
org.elasticsearch.search.fetch.FetchPhaseExecutionException.class,
Expand All @@ -520,7 +572,6 @@ public static <T extends Throwable> T writeStackTraces(T throwable, StreamOutput
org.elasticsearch.index.engine.RecoveryEngineException.class,
org.elasticsearch.common.blobstore.BlobStoreException.class,
org.elasticsearch.index.snapshots.IndexShardRestoreException.class,
org.elasticsearch.index.store.StoreException.class,
org.elasticsearch.index.query.QueryParsingException.class,
org.elasticsearch.action.support.replication.TransportReplicationAction.RetryOnPrimaryException.class,
org.elasticsearch.index.engine.DeleteByQueryFailedEngineException.class,
Expand All @@ -534,6 +585,9 @@ public static <T extends Throwable> T writeStackTraces(T throwable, StreamOutput
org.elasticsearch.index.engine.CreateFailedEngineException.class,
org.elasticsearch.index.shard.IllegalIndexShardStateException.class,
ElasticsearchSecurityException.class,
ResourceNotFoundException.class,
IndexNotFoundException.class,
ShardNotFoundException.class,
NotSerializableExceptionWrapper.class
};
Map<String, Constructor<? extends ElasticsearchException>> mapping = new HashMap<>(exceptions.length);
Expand All @@ -553,4 +607,58 @@ public static <T extends Throwable> T writeStackTraces(T throwable, StreamOutput
MAPPING = Collections.unmodifiableMap(mapping);
}

public String getIndex() {
List<String> index = getHeader(INDEX_HEADER_KEY);
if (index != null && index.isEmpty() == false) {
return index.get(0);
}

return null;
}

public ShardId getShardId() {
List<String> shard = getHeader(SHARD_HEADER_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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if index == null, do we want to clear the header?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no

addHeader(INDEX_HEADER_KEY, index.getName());
}
}

public void setIndex(String index) {
if (index != null) {
addHeader(INDEX_HEADER_KEY, index);
}
}

public void setShard(ShardId shardId) {
if (shardId != null) {
addHeader(INDEX_HEADER_KEY, shardId.getIndex());
addHeader(SHARD_HEADER_KEY, Integer.toString(shardId.id()));
}
}

public void setResources(String type, String... id) {
assert type != null;
addHeader(RESOURCE_HEADER_ID_KEY, id);
addHeader(RESOURCE_HEADER_TYPE_KEY, type);
}

public List<String> getResourceId() {
return getHeader(RESOURCE_HEADER_ID_KEY);
}

public String getResourceType() {
List<String> header = getHeader(RESOURCE_HEADER_TYPE_KEY);
if (header != null && header.isEmpty() == false) {
assert header.size() == 1;
return header.get(0);
}
return null;
}
}
8 changes: 3 additions & 5 deletions core/src/main/java/org/elasticsearch/ExceptionsHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexException;
import org.elasticsearch.rest.RestStatus;

import java.io.IOException;
Expand Down Expand Up @@ -240,12 +238,12 @@ public static ShardOperationFailedException[] groupBy(ShardOperationFailedExcept

static class GroupBy {
final String reason;
final Index index;
final String index;
final Class<? extends Throwable> causeType;

public GroupBy(Throwable t) {
if (t instanceof IndexException) {
index = ((IndexException) t).index();
if (t instanceof ElasticsearchException) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is great

index = ((ElasticsearchException) t).getIndex();
} else {
index = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,32 @@
* specific language governing permissions and limitations
* under the License.
*/

package org.elasticsearch.index;
package org.elasticsearch;

import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.index.shard.IndexShardException;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.rest.RestStatus;

import java.io.IOException;

/**
*
* Generic ResourceNotFoundException corresponding to the {@link RestStatus#NOT_FOUND} status code
*/
public class IndexShardMissingException extends IndexShardException {
public class ResourceNotFoundException extends ElasticsearchException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should also have a a es.resource.id header and have a method to add it - addResourceId (a la addIndex) ?


public ResourceNotFoundException(String msg, Object... args) {
super(msg, args);
}

public IndexShardMissingException(ShardId shardId) {
super(shardId, "missing");
protected ResourceNotFoundException(String msg, Throwable cause, Object... args) {
super(msg, cause, args);
}

public IndexShardMissingException(StreamInput in) throws IOException{
public ResourceNotFoundException(StreamInput in) throws IOException {
super(in);
}

@Override
public RestStatus status() {
public final RestStatus status() {
return RestStatus.NOT_FOUND;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@

package org.elasticsearch.action;

import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.index.shard.IndexShardException;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.rest.RestStatus;

Expand All @@ -29,18 +29,19 @@
/**
*
*/
public class NoShardAvailableActionException extends IndexShardException {
public class NoShardAvailableActionException extends ElasticsearchException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to make this a ResourceNotAvailableException?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'love this but I think it's worth another change?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK


public NoShardAvailableActionException(ShardId shardId) {
super(shardId, null);
this(shardId, null);
}

public NoShardAvailableActionException(ShardId shardId, String msg) {
super(shardId, msg);
this(shardId, msg, null);
}

public NoShardAvailableActionException(ShardId shardId, String msg, Throwable cause) {
super(shardId, msg, cause);
super(msg, cause);
setShard(shardId);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@
*/
public class RoutingMissingException extends ElasticsearchException {

private final String index;

private final String type;

private final String id;
Expand All @@ -43,20 +41,16 @@ public RoutingMissingException(String index, String type, String id) {
Objects.requireNonNull(index, "index must not be null");
Objects.requireNonNull(type, "type must not be null");
Objects.requireNonNull(id, "id must not be null");
this.index = index;
setIndex(index);
this.type = type;
this.id = id;
}

public String index() {
return index;
}

public String type() {
public String getType() {
return type;
}

public String id() {
public String getId() {
return id;
}

Expand All @@ -67,15 +61,13 @@ public RestStatus status() {

public RoutingMissingException(StreamInput in) throws IOException{
super(in);
index = in.readString();
type = in.readString();
id = in.readString();
}

@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeString(index);
out.writeString(type);
out.writeString(id);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.gateway.GatewayAllocator;
import org.elasticsearch.indices.IndexMissingException;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;

Expand Down Expand Up @@ -203,7 +203,7 @@ private boolean prepareResponse(final ClusterHealthRequest request, final Cluste
try {
indexNameExpressionResolver.concreteIndices(clusterState, IndicesOptions.strictExpand(), request.indices());
waitForCounter++;
} catch (IndexMissingException e) {
} catch (IndexNotFoundException e) {
response.status = ClusterHealthStatus.RED; // no indices, make sure its RED
// missing indices, wait a bit more...
}
Expand Down Expand Up @@ -269,7 +269,7 @@ private ClusterHealthResponse clusterHealth(ClusterHealthRequest request, Cluste
String[] concreteIndices;
try {
concreteIndices = indexNameExpressionResolver.concreteIndices(clusterState, request);
} catch (IndexMissingException e) {
} catch (IndexNotFoundException e) {
// one of the specified indices is not there - treat it as RED.
ClusterHealthResponse response = new ClusterHealthResponse(clusterName.value(), Strings.EMPTY_ARRAY, clusterState,
numberOfPendingTasks, numberOfInFlightFetch, UnassignedInfo.getNumberOfDelayedUnassigned(settings, clusterState),
Expand Down
Loading