Permalink
Browse files

always raise parse error exceptions in multi/exec pipelines as a resu…

  • Loading branch information...
1 parent 76d516a commit fe60fc97128eda8d0d12468cddd3cc5fd002232e andy committed Nov 16, 2012
Showing with 21 additions and 18 deletions.
  1. +7 −0 CHANGES
  2. +9 −2 redis/client.py
  3. +2 −0 redis/connection.py
  4. +3 −0 redis/exceptions.py
  5. +0 −16 tests/pipeline.py
View
@@ -1,3 +1,10 @@
+* 2.7.2
+ * Parse errors are now *always* raised on multi/exec pipelines, regardless
+ of the `raise_on_error` flag. See
+ https://groups.google.com/forum/?hl=en&fromgroups=#!topic/redis-db/VUiEFT8U8U0
+ for more info.
+* 2.7.1
+ * Packaged tests with source code
* 2.7.0
* Added BITOP and BITCOUNT commands. Thanks Mark Tozzi.
* Added the TIME command. Thanks Jason Knight.
View
@@ -13,7 +13,8 @@
RedisError,
ResponseError,
WatchError,
- NoScriptError
+ NoScriptError,
+ ExecAbortError,
)
SYM_EMPTY = b('')
@@ -1714,7 +1715,13 @@ def _execute_transaction(self, connection, commands, raise_on_error):
errors.append((i, sys.exc_info()[1]))
# parse the EXEC.
- response = self.parse_response(connection, '_')
+ try:
+ response = self.parse_response(connection, '_')
+ except ExecAbortError:
+ self.immediate_execute_command('DISCARD')
+ if errors:
+ raise errors[0][1]
+ raise sys.exc_info()[1]
if response is None:
raise WatchError("Watched variable changed.")
View
@@ -12,6 +12,7 @@
InvalidResponse,
AuthenticationError,
NoScriptError,
+ ExecAbortError,
)
try:
@@ -35,6 +36,7 @@ class PythonParser(object):
EXCEPTION_CLASSES = {
'ERR': ResponseError,
'NOSCRIPT': NoScriptError,
+ 'EXECABORT': ExecAbortError,
}
def __init__(self):
View
@@ -34,3 +34,6 @@ class WatchError(RedisError):
class NoScriptError(ResponseError):
pass
+
+class ExecAbortError(ResponseError):
+ pass
View
@@ -94,22 +94,6 @@ def test_exec_error_raised(self):
self.assertEquals(pipe.set('z', 'zzz').execute(), [True])
self.assertEquals(self.client['z'], b('zzz'))
- def test_parse_error_in_response(self):
- with self.client.pipeline() as pipe:
- # the zrem is invalid because we don't pass any keys to it
- pipe.set('a', 1).zrem('b').set('b', 2)
- result = pipe.execute(raise_on_error=False)
-
- self.assertEquals(result[0], True)
- self.assertEquals(self.client['a'], b('1'))
- self.assert_(isinstance(result[1], redis.ResponseError))
- self.assertEquals(result[2], True)
- self.assertEquals(self.client['b'], b('2'))
-
- # make sure the pipe was restored to a working state
- self.assertEquals(pipe.set('z', 'zzz').execute(), [True])
- self.assertEquals(self.client['z'], b('zzz'))
-
def test_parse_error_raised(self):
with self.client.pipeline() as pipe:
# the zrem is invalid because we don't pass any keys to it

0 comments on commit fe60fc9

Please sign in to comment.