Carry on rest status if exceptions are not serializable

Today we loose the RestStatus code for non-serializable exceptions.
This can be tricky if they are supposed to signal certain situations
like authentication errors etc. This commit adds support for carrying on
the exceptions in the NotSerializableExceptoinWrapper
This commit is contained in:
Simon Willnauer 2015-07-01 13:57:54 +02:00
parent 74cf05595e
commit 93acb98bd6
2 changed files with 31 additions and 7 deletions

View File

@ -20,7 +20,9 @@
package org.elasticsearch.common.io.stream; package org.elasticsearch.common.io.stream;
import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.rest.RestStatus;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.Collections;
@ -37,10 +39,12 @@ import java.util.Map;
public final class NotSerializableExceptionWrapper extends ElasticsearchException.WithRestHeadersException { public final class NotSerializableExceptionWrapper extends ElasticsearchException.WithRestHeadersException {
private final String name; private final String name;
private final RestStatus status;
public NotSerializableExceptionWrapper(Throwable other, Map<String, List<String>> headers) { public NotSerializableExceptionWrapper(Throwable other, Map<String, List<String>> headers) {
super(other.getMessage(), other.getCause(), headers); super(other.getMessage(), other.getCause(), headers);
this.name = ElasticsearchException.getExceptionName(other); this.name = ElasticsearchException.getExceptionName(other);
this.status = ExceptionsHelper.status(other);
setStackTrace(other.getStackTrace()); setStackTrace(other.getStackTrace());
for (Throwable otherSuppressed : other.getSuppressed()) { for (Throwable otherSuppressed : other.getSuppressed()) {
addSuppressed(otherSuppressed); addSuppressed(otherSuppressed);
@ -58,16 +62,23 @@ public final class NotSerializableExceptionWrapper extends ElasticsearchExceptio
public NotSerializableExceptionWrapper(StreamInput in) throws IOException { public NotSerializableExceptionWrapper(StreamInput in) throws IOException {
super(in); super(in);
name = in.readString(); name = in.readString();
status = RestStatus.readFrom(in);
} }
@Override @Override
public void writeTo(StreamOutput out) throws IOException { public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out); super.writeTo(out);
out.writeString(name); out.writeString(name);
RestStatus.writeTo(out, status);
} }
@Override @Override
protected String getExceptionName() { protected String getExceptionName() {
return name; return name;
} }
@Override
public RestStatus status() {
return status;
}
} }

View File

@ -55,6 +55,7 @@ import org.elasticsearch.indices.InvalidIndexTemplateException;
import org.elasticsearch.indices.recovery.RecoverFilesRecoveryException; import org.elasticsearch.indices.recovery.RecoverFilesRecoveryException;
import org.elasticsearch.percolator.PercolateException; import org.elasticsearch.percolator.PercolateException;
import org.elasticsearch.repositories.RepositoryException; import org.elasticsearch.repositories.RepositoryException;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.action.admin.indices.alias.delete.AliasesMissingException; import org.elasticsearch.rest.action.admin.indices.alias.delete.AliasesMissingException;
import org.elasticsearch.search.SearchContextMissingException; import org.elasticsearch.search.SearchContextMissingException;
import org.elasticsearch.search.SearchException; import org.elasticsearch.search.SearchException;
@ -588,18 +589,30 @@ public class ExceptionSerializationTests extends ElasticsearchTestCase {
assertEquals("foo", ex.getHeaders().get("foo").get(0)); assertEquals("foo", ex.getHeaders().get("foo").get(0));
assertEquals("bar", ex.getHeaders().get("foo").get(1)); assertEquals("bar", ex.getHeaders().get("foo").get(1));
RestStatus status = randomFrom(RestStatus.values());
// ensure we are carrying over the headers even if not serialized // ensure we are carrying over the headers even if not serialized
ElasticsearchException e = serialize((ElasticsearchException)new UnknownHeaderException("msg", new Tuple("foo", new String[]{"foo", "bar"}))); ElasticsearchException serialize = serialize((ElasticsearchException) new UnknownHeaderException("msg", status, new Tuple("foo", new String[]{"foo", "bar"})));
assertTrue(e instanceof NotSerializableExceptionWrapper); assertTrue(serialize instanceof NotSerializableExceptionWrapper);
assertEquals("msg", ex.getMessage()); NotSerializableExceptionWrapper e = (NotSerializableExceptionWrapper) serialize;
assertEquals(2, ex.getHeaders().get("foo").size()); assertEquals("msg", e.getMessage());
assertEquals("foo", ex.getHeaders().get("foo").get(0)); assertEquals(2, e.getHeaders().get("foo").size());
assertEquals("bar", ex.getHeaders().get("foo").get(1)); assertEquals("foo", e.getHeaders().get("foo").get(0));
assertEquals("bar", e.getHeaders().get("foo").get(1));
assertSame(status, e.status());
} }
public static class UnknownHeaderException extends ElasticsearchException.WithRestHeadersException { public static class UnknownHeaderException extends ElasticsearchException.WithRestHeadersException {
public UnknownHeaderException(String msg, Tuple<String, String[]>... headers) { private final RestStatus status;
public UnknownHeaderException(String msg, RestStatus status, Tuple<String, String[]>... headers) {
super(msg, headers); super(msg, headers);
this.status = status;
}
@Override
public RestStatus status() {
return status;
} }
} }
} }