diff --git a/src/main/java/org/springframework/data/redis/connection/RedisPipelineException.java b/src/main/java/org/springframework/data/redis/connection/RedisPipelineException.java
new file mode 100644
index 000000000..6f1a514f7
--- /dev/null
+++ b/src/main/java/org/springframework/data/redis/connection/RedisPipelineException.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2011-2012 the original author or authors.
+ *
+ * Licensed 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.springframework.data.redis.connection;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.springframework.dao.InvalidDataAccessResourceUsageException;
+
+/**
+ * Exception thrown when executing/closing a pipeline that contains one or multiple invalid/incorrect statements.
+ * The exception contains the pipeline result, allowing for analysis and tracing.
+ *
+ * Typically, the first exception returned by the pipeline is used as the cause of this exception for easier
+ * debugging.
+ *
+ * @author Costin Leau
+ */
+public class RedisPipelineException extends InvalidDataAccessResourceUsageException {
+
+ private final List results;
+
+ /**
+ * Constructs a new RedisPipelineException instance.
+ *
+ * @param msg the message
+ * @param cause the cause
+ * @param pipelineResult the pipeline result
+ */
+ public RedisPipelineException(String msg, Throwable cause, List pipelineResult) {
+ super(msg, cause);
+ results = Collections.unmodifiableList(pipelineResult);
+ }
+
+ /**
+ * Constructs a new RedisPipelineException instance using a default message.
+ *
+ * @param cause the cause
+ * @param pipelineResult the pipeline result
+ */
+ public RedisPipelineException(Exception cause, List pipelineResult) {
+ this("Pipeline contained one or more invalid commands", cause, pipelineResult);
+ }
+
+
+ /**
+ * Constructs a new RedisPipelineException instance.
+ *
+ * @param msg message
+ * @param pipelineResult pipeline partial results
+ */
+ public RedisPipelineException(String msg, List pipelineResult) {
+ super(msg);
+ results = Collections.unmodifiableList(pipelineResult);
+ }
+
+ /**
+ * Returns the result of the pipeline that caused the exception.
+ * Typically contains both the results of the successful statements but also
+ * the exceptions of the incorrect ones.
+ *
+ * @return result of the pipeline
+ */
+ public List getPipelineResult() {
+ return results;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java
index 746f6178d..d43ae07de 100644
--- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java
@@ -30,6 +30,7 @@ import org.springframework.data.redis.RedisSystemException;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnection;
+import org.springframework.data.redis.connection.RedisPipelineException;
import org.springframework.data.redis.connection.RedisSubscribedConnectionException;
import org.springframework.data.redis.connection.SortParameters;
import org.springframework.data.redis.connection.Subscription;
@@ -68,8 +69,8 @@ public class JedisConnection implements RedisConnection {
static {
CLIENT_FIELD = ReflectionUtils.findField(BinaryJedis.class, "client", Client.class);
ReflectionUtils.makeAccessible(CLIENT_FIELD);
- SEND_COMMAND = ReflectionUtils.findMethod(Connection.class, "sendCommand",
- new Class[] { Command.class, byte[][].class });
+ SEND_COMMAND = ReflectionUtils.findMethod(Connection.class, "sendCommand", new Class[] { Command.class,
+ byte[][].class });
ReflectionUtils.makeAccessible(SEND_COMMAND);
GET_RESPONSE = ReflectionUtils.findMethod(Queable.class, "getResponse", Builder.class);
ReflectionUtils.makeAccessible(GET_RESPONSE);
@@ -135,27 +136,33 @@ public class JedisConnection implements RedisConnection {
public Object execute(String command, byte[]... args) {
Assert.hasText(command, "a valid command needs to be specified");
- List mArgs = new ArrayList();
- if (!ObjectUtils.isEmpty(args)) {
- Collections.addAll(mArgs, args);
+ try {
+ List mArgs = new ArrayList();
+ if (!ObjectUtils.isEmpty(args)) {
+ Collections.addAll(mArgs, args);
+ }
+
+ Object result = ReflectionUtils.invokeMethod(SEND_COMMAND, client,
+ Command.valueOf(command.trim().toUpperCase()), mArgs.toArray(new byte[mArgs.size()][]));
+ if (isQueueing() || isPipelined()) {
+ Object target = (isPipelined() ? pipeline : transaction);
+ ReflectionUtils.invokeMethod(GET_RESPONSE, target, new Builder() {
+ public Object build(Object data) {
+ return data;
+ }
+
+ public String toString() {
+ return "Object";
+ }
+ });
+ }
+ else {
+ client.getOne();
+ }
+ return result;
+ } catch (Exception ex) {
+ throw convertJedisAccessException(ex);
}
-
- Object result = ReflectionUtils.invokeMethod(SEND_COMMAND, client,
- Command.valueOf(command.trim().toUpperCase()), mArgs.toArray(new byte[mArgs.size()][]));
- if (isQueueing() || isPipelined()) {
- Object target = (isPipelined() ? pipeline : transaction);
- ReflectionUtils.invokeMethod(GET_RESPONSE, target, new Builder() {
- public Object build(Object data) {
- return data;
- }
-
- public String toString() {
- return "Object";
- }
- });
- }
-
- return result;
}
public void close() throws DataAccessException {
@@ -232,13 +239,25 @@ public class JedisConnection implements RedisConnection {
if (pipeline != null) {
List execute = pipeline.syncAndReturnAll();
if (execute != null && !execute.isEmpty()) {
- return execute;
+ Exception cause = null;
+ for (int i = 0; i < execute.size(); i++) {
+ Object object = execute.get(i);
+ if (object instanceof Exception) {
+ DataAccessException dataAccessException = convertJedisAccessException((Exception) object);
+ if (cause == null) {
+ cause = dataAccessException;
+ }
+ execute.set(i, dataAccessException);
+ }
+ }
+ if (cause != null) {
+ throw new RedisPipelineException(cause, execute);
+ }
}
}
return Collections.emptyList();
}
-
public List sort(byte[] key, SortParameters params) {
SortingParams sortParams = JedisUtils.convertSortParams(params);
diff --git a/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java b/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java
index f0cdc25d1..d99e7dbe1 100644
--- a/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/jredis/JredisConnection.java
@@ -89,14 +89,17 @@ public class JredisConnection implements RedisConnection {
public Object execute(String command, byte[]... args) {
Assert.hasText(command, "a valid command needs to be specified");
- List mArgs = new ArrayList();
- if (!ObjectUtils.isEmpty(args)) {
- Collections.addAll(mArgs, args);
+ try {
+ List mArgs = new ArrayList();
+ if (!ObjectUtils.isEmpty(args)) {
+ Collections.addAll(mArgs, args);
+ }
+
+ return ReflectionUtils.invokeMethod(SERVICE_REQUEST, jredis, Command.valueOf(command.trim().toUpperCase()),
+ mArgs.toArray(new byte[mArgs.size()][]));
+ } catch (Exception ex) {
+ throw convertJredisAccessException(ex);
}
-
- return ReflectionUtils.invokeMethod(SERVICE_REQUEST, jredis, Command.valueOf(command.trim().toUpperCase()),
- mArgs.toArray(new byte[mArgs.size()][]));
-
}
public void close() throws RedisSystemException {
diff --git a/src/main/java/org/springframework/data/redis/connection/rjc/RjcConnection.java b/src/main/java/org/springframework/data/redis/connection/rjc/RjcConnection.java
index 621dc9591..3d203e587 100644
--- a/src/main/java/org/springframework/data/redis/connection/rjc/RjcConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/rjc/RjcConnection.java
@@ -83,9 +83,16 @@ public class RjcConnection implements RedisConnection {
public Object execute(String command, byte[]... args) {
Assert.hasText(command, "a valid command needs to be specified");
- connection.sendCommand(Command.valueOf(command.trim().toUpperCase()),
- (ObjectUtils.isEmpty(args) ? new byte[0][] : args));
- return connection.getAll();
+ try {
+ connection.sendCommand(Command.valueOf(command.trim().toUpperCase()),
+ (ObjectUtils.isEmpty(args) ? new byte[0][] : args));
+ if (!isPipelined()) {
+ return connection.getAll();
+ }
+ return null;
+ } catch (Exception ex) {
+ throw convertRjcAccessException(ex);
+ }
}
public void close() throws DataAccessException {
diff --git a/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java b/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java
index b7bfa2617..b31b2ab13 100644
--- a/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java
+++ b/src/main/java/org/springframework/data/redis/connection/srp/SrpConnection.java
@@ -80,14 +80,18 @@ public class SrpConnection implements RedisConnection {
public Object execute(String command, byte[]... args) {
Assert.hasText(command, "a valid command needs to be specified");
- String name = command.trim().toUpperCase();
- Command cmd = new Command(name.getBytes(Charsets.UTF_8), args);
- if (isPipelined()) {
- client.pipeline(name, cmd);
- return null;
- }
- else {
- return client.execute(name, cmd);
+ try {
+ String name = command.trim().toUpperCase();
+ Command cmd = new Command(name.getBytes(Charsets.UTF_8), args);
+ if (isPipelined()) {
+ client.pipeline(name, cmd);
+ return null;
+ }
+ else {
+ return client.execute(name, cmd);
+ }
+ } catch (RedisException ex) {
+ throw convertSRAccessException(ex);
}
}
diff --git a/src/test/java/org/springframework/data/redis/connection/jredis/JRedisConnectionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/jredis/JRedisConnectionIntegrationTests.java
index c38a6134c..8d92a6397 100644
--- a/src/test/java/org/springframework/data/redis/connection/jredis/JRedisConnectionIntegrationTests.java
+++ b/src/test/java/org/springframework/data/redis/connection/jredis/JRedisConnectionIntegrationTests.java
@@ -91,4 +91,8 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat
public void testBitSet() throws Exception {
}
+ @Ignore
+ public void exceptionExecuteNativeWithPipeline() throws Exception {
+ }
+
}
\ No newline at end of file