DATAREDIS-603 - Fall back to RedisSystemException for non translateable exceptions during cluster execution.

We now use a fallback exception translation strategy in JedisClusterConnection to map all non-mapped exceptions to RedisSystemException. This change prevents null pointer exceptions caused by potentially throwing null.

Original Pull Request: #275
This commit is contained in:
Mark Paluch
2017-09-06 16:07:19 +02:00
committed by Christoph Strobl
parent 2dd172e771
commit 06c37880f7
6 changed files with 92 additions and 26 deletions

View File

@@ -16,6 +16,7 @@
package org.springframework.data.redis.connection.jedis;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;
import static org.mockito.Matchers.anyVararg;
import static org.mockito.Matchers.eq;
@@ -48,6 +49,7 @@ import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import org.springframework.data.redis.ClusterStateFailureException;
import org.springframework.data.redis.RedisSystemException;
import org.springframework.data.redis.connection.ClusterInfo;
import org.springframework.data.redis.connection.RedisClusterCommands.AddSlots;
import org.springframework.data.redis.connection.RedisClusterNode;
@@ -108,7 +110,7 @@ public class JedisClusterConnectionUnitTests {
}
@Test // DATAREDIS-315
public void thowsExceptionWhenClusterCommandExecturorIsNull() {
public void throwsExceptionWhenClusterCommandExecutorIsNull() {
expectedException.expect(IllegalArgumentException.class);
@@ -353,6 +355,20 @@ public class JedisClusterConnectionUnitTests {
new JedisClusterTopologyProvider(clusterMock).getTopology();
}
@Test // DATAREDIS-603
public void translatesUnknownExceptions() {
IllegalArgumentException exception = new IllegalArgumentException("Aw, snap!");
expectedException.expect(RedisSystemException.class);
expectedException.expectMessage(exception.getMessage());
expectedException.expectCause(is(exception));
when(clusterMock.set("foo".getBytes(), "bar".getBytes())).thenThrow(exception);
connection.set("foo".getBytes(), "bar".getBytes());
}
static class StubJedisCluster extends JedisCluster {
JedisClusterConnectionHandler connectionHandler;

View File

@@ -15,6 +15,8 @@
*/
package org.springframework.data.redis.connection.lettuce;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;
@@ -25,6 +27,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.mockito.Mockito;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.data.redis.connection.AbstractConnectionUnitTestBase;
import org.springframework.data.redis.connection.RedisServerCommands.ShutdownOption;
@@ -32,10 +35,12 @@ import org.springframework.data.redis.connection.lettuce.LettuceConnectionUnitTe
import org.springframework.data.redis.connection.lettuce.LettuceConnectionUnitTestSuite.LettucePipelineConnectionUnitTests;
import com.lambdaworks.redis.RedisClient;
import com.lambdaworks.redis.RedisFuture;
import com.lambdaworks.redis.api.StatefulRedisConnection;
import com.lambdaworks.redis.api.async.RedisAsyncCommands;
import com.lambdaworks.redis.api.sync.RedisCommands;
import com.lambdaworks.redis.codec.RedisCodec;
import com.lambdaworks.redis.protocol.RedisCommand;
/**
* @author Christoph Strobl
@@ -138,6 +143,43 @@ public class LettuceConnectionUnitTestSuite {
verify(syncCommandsMock, times(1)).select(1);
}
@Test // DATAREDIS-603
public void translatesUnknownExceptions() {
IllegalArgumentException exception = new IllegalArgumentException("Aw, snap!");
when(syncCommandsMock.set(any(), any())).thenThrow(exception);
connection = new LettuceConnection(null, 0, clientMock, null, 1);
try {
connection.set("foo".getBytes(), "bar".getBytes());
} catch (Exception e) {
assertThat(e.getMessage(), containsString(exception.getMessage()));
assertThat(e.getCause(), is((Throwable) exception));
}
}
@Test // DATAREDIS-603
public void translatesPipelineUnknownExceptions() throws Exception {
IllegalArgumentException exception = new IllegalArgumentException("Aw, snap!");
RedisCommand future = mock(RedisCommand.class, Mockito.withSettings().extraInterfaces(RedisFuture.class));
when(future.getOutput()).thenThrow(exception);
when(asyncCommandsMock.set(any(byte[].class), any(byte[].class))).thenReturn((RedisFuture) future);
connection = new LettuceConnection(null, 0, clientMock, null, 1);
connection.openPipeline();
try {
connection.set("foo".getBytes(), "bar".getBytes());
} catch (Exception e) {
assertThat(e.getMessage(), containsString(exception.getMessage()));
assertThat(e.getCause(), is((Throwable) exception));
}
}
}
public static class LettucePipelineConnectionUnitTests extends LettuceConnectionUnitTests {