diff --git a/server/src/main/java/org/elasticsearch/gateway/GatewayMetaState.java b/server/src/main/java/org/elasticsearch/gateway/GatewayMetaState.java index 9b137070cb8cd..c5bfa9224900a 100644 --- a/server/src/main/java/org/elasticsearch/gateway/GatewayMetaState.java +++ b/server/src/main/java/org/elasticsearch/gateway/GatewayMetaState.java @@ -22,6 +22,7 @@ import com.carrotsearch.hppc.cursors.ObjectObjectCursor; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.message.ParameterizedMessage; import org.elasticsearch.Version; import org.elasticsearch.cluster.ClusterChangedEvent; import org.elasticsearch.cluster.ClusterName; @@ -235,8 +236,8 @@ public void setCurrentTerm(long currentTerm) { try { innerSetCurrentTerm(currentTerm); } catch (WriteStateException e) { - logger.warn("Exception occurred when setting current term", e); - //TODO re-throw exception + logger.error(new ParameterizedMessage("Failed to set current term to {}", currentTerm), e); + e.rethrowAsErrorOrUncheckedException(); } } @@ -253,8 +254,8 @@ public void setLastAcceptedState(ClusterState clusterState) { incrementalWrite = previousClusterState.term() == clusterState.term(); updateClusterState(clusterState, previousClusterState); } catch (WriteStateException e) { - logger.warn("Exception occurred when setting last accepted state", e); - //TODO re-throw exception + logger.error(new ParameterizedMessage("Failed to set last accepted state with version {}", clusterState.version()), e); + e.rethrowAsErrorOrUncheckedException(); } } diff --git a/server/src/main/java/org/elasticsearch/gateway/WriteStateException.java b/server/src/main/java/org/elasticsearch/gateway/WriteStateException.java index aeb9bffc6711d..29699be2c16a0 100644 --- a/server/src/main/java/org/elasticsearch/gateway/WriteStateException.java +++ b/server/src/main/java/org/elasticsearch/gateway/WriteStateException.java @@ -18,7 +18,9 @@ */ package org.elasticsearch.gateway; +import java.io.IOError; import java.io.IOException; +import java.io.UncheckedIOException; /** * This exception is thrown when there is a problem of writing state to disk. @@ -38,4 +40,16 @@ public class WriteStateException extends IOException { public boolean isDirty() { return dirty; } + + /** + * Rethrows this {@link WriteStateException} as {@link IOError} if dirty flag is set, which will lead to JVM shutdown. + * If dirty flag is not set, this exception is wrapped into {@link UncheckedIOException}. + */ + public void rethrowAsErrorOrUncheckedException() { + if (isDirty()) { + throw new IOError(this); + } else { + throw new UncheckedIOException(this); + } + } } diff --git a/server/src/test/java/org/elasticsearch/gateway/WriteStateExceptionTests.java b/server/src/test/java/org/elasticsearch/gateway/WriteStateExceptionTests.java new file mode 100644 index 0000000000000..cc6a7950d8920 --- /dev/null +++ b/server/src/test/java/org/elasticsearch/gateway/WriteStateExceptionTests.java @@ -0,0 +1,49 @@ +/* + * 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.gateway; + +import org.elasticsearch.test.ESTestCase; + +import java.io.IOError; +import java.io.UncheckedIOException; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; + +public class WriteStateExceptionTests extends ESTestCase { + + public void testDirtyFlag() { + boolean dirty = randomBoolean(); + WriteStateException ex = new WriteStateException(dirty, "test", null); + assertThat(ex.isDirty(), equalTo(dirty)); + } + + public void testNonDirtyRethrow() { + WriteStateException ex = new WriteStateException(false, "test", null); + UncheckedIOException ex2 = expectThrows(UncheckedIOException.class, () -> ex.rethrowAsErrorOrUncheckedException()); + assertThat(ex2.getCause(), instanceOf(WriteStateException.class)); + } + + public void testDirtyRethrow() { + WriteStateException ex = new WriteStateException(true, "test", null); + IOError err = expectThrows(IOError.class, () -> ex.rethrowAsErrorOrUncheckedException()); + assertThat(err.getCause(), instanceOf(WriteStateException.class)); + } +}