Skip to content

Commit bc7ee7e

Browse files
committed
Fix ResponseFuture._set_result crashes on connection error when used with PrepareMessage
1 parent 23cbf90 commit bc7ee7e

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

CHANGELOG.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ Features
1111
Bug Fixes
1212
---------
1313
* re-raising the CQLEngineException will fail on Python 3 (PYTHON-1166)
14-
* Connection fails to validate ssl certificate hostname when SSLContext.check_hostname is set
14+
* Connection fails to validate ssl certificate hostname when SSLContext.check_hostname is set (PYTHON-1186)
15+
* ResponseFuture._set_result crashes on connection error when used with PrepareMessage (PYTHON-1187)
1516

1617
3.20.2
1718
======

cassandra/cluster.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4059,8 +4059,9 @@ def _set_result(self, host, connection, pool, response):
40594059
log.warning("Host %s error: %s.", host, response.summary)
40604060
if self._metrics is not None:
40614061
self._metrics.on_other_error()
4062+
cl = getattr(self.message, 'consistency_level', None)
40624063
retry = retry_policy.on_request_error(
4063-
self.query, self.message.consistency_level, error=response,
4064+
self.query, cl, error=response,
40644065
retry_num=self._query_retries)
40654066
elif isinstance(response, PreparedQueryNotFound):
40664067
if self.prepared_statement:
@@ -4117,9 +4118,9 @@ def _set_result(self, host, connection, pool, response):
41174118
self._metrics.on_connection_error()
41184119
if not isinstance(response, ConnectionShutdown):
41194120
self._connection.defunct(response)
4121+
cl = getattr(self.message, 'consistency_level', None)
41204122
retry = self._retry_policy.on_request_error(
4121-
self.query, self.message.consistency_level, error=response,
4122-
retry_num=self._query_retries)
4123+
self.query, cl, error=response, retry_num=self._query_retries)
41234124
self._handle_retry_decision(retry, response, host)
41244125
elif isinstance(response, Exception):
41254126
if hasattr(response, 'to_exception'):

tests/unit/test_response_future.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,28 @@ def test_unavailable_error_message(self):
200200
rf._set_result(None, None, None, result)
201201
self.assertRaises(Exception, rf.result)
202202

203+
def test_request_error_with_prepare_message(self):
204+
session = self.make_session()
205+
query = SimpleStatement("SELECT * FROM foobar")
206+
retry_policy = Mock()
207+
retry_policy.on_request_error.return_value = (RetryPolicy.RETHROW, None)
208+
message = PrepareMessage(query=query)
209+
210+
rf = ResponseFuture(session, message, query, 1, retry_policy=retry_policy)
211+
rf._query_retries = 1
212+
rf.send_request()
213+
result = Mock(spec=OverloadedErrorMessage)
214+
result.to_exception.return_value = result
215+
rf._set_result(None, None, None, result)
216+
self.assertIsInstance(rf._final_exception, OverloadedErrorMessage)
217+
218+
rf = ResponseFuture(session, message, query, 1, retry_policy=retry_policy)
219+
rf._query_retries = 1
220+
rf.send_request()
221+
result = Mock(spec=ConnectionException)
222+
rf._set_result(None, None, None, result)
223+
self.assertIsInstance(rf._final_exception, ConnectionException)
224+
203225
def test_retry_policy_says_ignore(self):
204226
session = self.make_session()
205227
query = SimpleStatement("INSERT INFO foo (a, b) VALUES (1, 2)")

0 commit comments

Comments
 (0)