Support v5 error code map for failure messages
Done for PYTHON-619
This commit is contained in:
@@ -325,16 +325,34 @@ class CoordinationFailure(RequestExecutionException):
|
|||||||
The number of replicas that sent a failure message
|
The number of replicas that sent a failure message
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, summary_message, consistency=None, required_responses=None, received_responses=None, failures=None):
|
error_code_map = None
|
||||||
|
"""
|
||||||
|
A map of inet addresses to error codes representing replicas that sent
|
||||||
|
a failure message. Only set when `protocol_version` is 5 or higher.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, summary_message, consistency=None, required_responses=None,
|
||||||
|
received_responses=None, failures=None, error_code_map=None):
|
||||||
self.consistency = consistency
|
self.consistency = consistency
|
||||||
self.required_responses = required_responses
|
self.required_responses = required_responses
|
||||||
self.received_responses = received_responses
|
self.received_responses = received_responses
|
||||||
self.failures = failures
|
self.failures = failures
|
||||||
Exception.__init__(self, summary_message + ' info=' +
|
self.error_code_map = error_code_map
|
||||||
repr({'consistency': consistency_value_to_name(consistency),
|
|
||||||
'required_responses': required_responses,
|
info_dict = {
|
||||||
'received_responses': received_responses,
|
'consistency': consistency_value_to_name(consistency),
|
||||||
'failures': failures}))
|
'required_responses': required_responses,
|
||||||
|
'received_responses': received_responses,
|
||||||
|
'failures': failures
|
||||||
|
}
|
||||||
|
|
||||||
|
if error_code_map is not None:
|
||||||
|
# make error codes look like "0x002a"
|
||||||
|
formatted_map = dict((addr, '0x%04x' % err_code)
|
||||||
|
for (addr, err_code) in error_code_map.items())
|
||||||
|
info_dict['error_code_map'] = formatted_map
|
||||||
|
|
||||||
|
Exception.__init__(self, summary_message + ' info=' + repr(info_dict))
|
||||||
|
|
||||||
|
|
||||||
class ReadFailure(CoordinationFailure):
|
class ReadFailure(CoordinationFailure):
|
||||||
|
|||||||
@@ -127,11 +127,11 @@ class ErrorMessage(_MessageType, Exception):
|
|||||||
self.info = info
|
self.info = info
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def recv_body(cls, f, *args):
|
def recv_body(cls, f, protocol_version, *args):
|
||||||
code = read_int(f)
|
code = read_int(f)
|
||||||
msg = read_string(f)
|
msg = read_string(f)
|
||||||
subcls = error_classes.get(code, cls)
|
subcls = error_classes.get(code, cls)
|
||||||
extra_info = subcls.recv_error_info(f)
|
extra_info = subcls.recv_error_info(f, protocol_version)
|
||||||
return subcls(code=code, message=msg, info=extra_info)
|
return subcls(code=code, message=msg, info=extra_info)
|
||||||
|
|
||||||
def summary_msg(self):
|
def summary_msg(self):
|
||||||
@@ -146,7 +146,7 @@ class ErrorMessage(_MessageType, Exception):
|
|||||||
__repr__ = __str__
|
__repr__ = __str__
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def recv_error_info(f):
|
def recv_error_info(f, protocol_version):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def to_exception(self):
|
def to_exception(self):
|
||||||
@@ -192,7 +192,7 @@ class UnavailableErrorMessage(RequestExecutionException):
|
|||||||
error_code = 0x1000
|
error_code = 0x1000
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def recv_error_info(f):
|
def recv_error_info(f, protocol_version):
|
||||||
return {
|
return {
|
||||||
'consistency': read_consistency_level(f),
|
'consistency': read_consistency_level(f),
|
||||||
'required_replicas': read_int(f),
|
'required_replicas': read_int(f),
|
||||||
@@ -223,7 +223,7 @@ class WriteTimeoutErrorMessage(RequestExecutionException):
|
|||||||
error_code = 0x1100
|
error_code = 0x1100
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def recv_error_info(f):
|
def recv_error_info(f, protocol_version):
|
||||||
return {
|
return {
|
||||||
'consistency': read_consistency_level(f),
|
'consistency': read_consistency_level(f),
|
||||||
'received_responses': read_int(f),
|
'received_responses': read_int(f),
|
||||||
@@ -240,7 +240,7 @@ class ReadTimeoutErrorMessage(RequestExecutionException):
|
|||||||
error_code = 0x1200
|
error_code = 0x1200
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def recv_error_info(f):
|
def recv_error_info(f, protocol_version):
|
||||||
return {
|
return {
|
||||||
'consistency': read_consistency_level(f),
|
'consistency': read_consistency_level(f),
|
||||||
'received_responses': read_int(f),
|
'received_responses': read_int(f),
|
||||||
@@ -257,13 +257,27 @@ class ReadFailureMessage(RequestExecutionException):
|
|||||||
error_code = 0x1300
|
error_code = 0x1300
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def recv_error_info(f):
|
def recv_error_info(f, protocol_version):
|
||||||
|
consistency = read_consistency_level(f)
|
||||||
|
received_responses = read_int(f)
|
||||||
|
required_responses = read_int(f)
|
||||||
|
|
||||||
|
if protocol_version >= 5:
|
||||||
|
error_code_map = read_error_code_map(f)
|
||||||
|
failures = len(error_code_map)
|
||||||
|
else:
|
||||||
|
error_code_map = None
|
||||||
|
failures = read_int(f)
|
||||||
|
|
||||||
|
data_retrieved = bool(read_byte(f))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'consistency': read_consistency_level(f),
|
'consistency': consistency,
|
||||||
'received_responses': read_int(f),
|
'received_responses': received_responses,
|
||||||
'required_responses': read_int(f),
|
'required_responses': required_responses,
|
||||||
'failures': read_int(f),
|
'failures': failures,
|
||||||
'data_retrieved': bool(read_byte(f)),
|
'error_code_map': error_code_map,
|
||||||
|
'data_retrieved': data_retrieved
|
||||||
}
|
}
|
||||||
|
|
||||||
def to_exception(self):
|
def to_exception(self):
|
||||||
@@ -275,7 +289,7 @@ class FunctionFailureMessage(RequestExecutionException):
|
|||||||
error_code = 0x1400
|
error_code = 0x1400
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def recv_error_info(f):
|
def recv_error_info(f, protocol_version):
|
||||||
return {
|
return {
|
||||||
'keyspace': read_string(f),
|
'keyspace': read_string(f),
|
||||||
'function': read_string(f),
|
'function': read_string(f),
|
||||||
@@ -291,13 +305,27 @@ class WriteFailureMessage(RequestExecutionException):
|
|||||||
error_code = 0x1500
|
error_code = 0x1500
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def recv_error_info(f):
|
def recv_error_info(f, protocol_version):
|
||||||
|
consistency = read_consistency_level(f)
|
||||||
|
received_responses = read_int(f)
|
||||||
|
required_responses = read_int(f)
|
||||||
|
|
||||||
|
if protocol_version >= 5:
|
||||||
|
error_code_map = read_error_code_map(f)
|
||||||
|
failures = len(error_code_map)
|
||||||
|
else:
|
||||||
|
error_code_map = None
|
||||||
|
failures = read_int(f)
|
||||||
|
|
||||||
|
write_type = WriteType.name_to_value[read_string(f)]
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'consistency': read_consistency_level(f),
|
'consistency': consistency,
|
||||||
'received_responses': read_int(f),
|
'received_responses': received_responses,
|
||||||
'required_responses': read_int(f),
|
'required_responses': required_responses,
|
||||||
'failures': read_int(f),
|
'failures': failures,
|
||||||
'write_type': WriteType.name_to_value[read_string(f)],
|
'error_code_map': error_code_map,
|
||||||
|
'write_type': write_type
|
||||||
}
|
}
|
||||||
|
|
||||||
def to_exception(self):
|
def to_exception(self):
|
||||||
@@ -335,7 +363,7 @@ class PreparedQueryNotFound(RequestValidationException):
|
|||||||
error_code = 0x2500
|
error_code = 0x2500
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def recv_error_info(f):
|
def recv_error_info(f, protocol_version):
|
||||||
# return the query ID
|
# return the query ID
|
||||||
return read_binary_string(f)
|
return read_binary_string(f)
|
||||||
|
|
||||||
@@ -345,7 +373,7 @@ class AlreadyExistsException(ConfigurationException):
|
|||||||
error_code = 0x2400
|
error_code = 0x2400
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def recv_error_info(f):
|
def recv_error_info(f, protocol_version):
|
||||||
return {
|
return {
|
||||||
'keyspace': read_string(f),
|
'keyspace': read_string(f),
|
||||||
'table': read_string(f),
|
'table': read_string(f),
|
||||||
@@ -1224,6 +1252,15 @@ def write_stringmultimap(f, strmmap):
|
|||||||
write_stringlist(f, v)
|
write_stringlist(f, v)
|
||||||
|
|
||||||
|
|
||||||
|
def read_error_code_map(f):
|
||||||
|
numpairs = read_int(f)
|
||||||
|
error_code_map = {}
|
||||||
|
for _ in range(numpairs):
|
||||||
|
endpoint = read_inet_addr_only(f)
|
||||||
|
error_code_map[endpoint] = read_short(f)
|
||||||
|
return error_code_map
|
||||||
|
|
||||||
|
|
||||||
def read_value(f):
|
def read_value(f):
|
||||||
size = read_int(f)
|
size = read_int(f)
|
||||||
if size < 0:
|
if size < 0:
|
||||||
@@ -1241,17 +1278,22 @@ def write_value(f, v):
|
|||||||
f.write(v)
|
f.write(v)
|
||||||
|
|
||||||
|
|
||||||
def read_inet(f):
|
def read_inet_addr_only(f):
|
||||||
size = read_byte(f)
|
size = read_byte(f)
|
||||||
addrbytes = f.read(size)
|
addrbytes = f.read(size)
|
||||||
port = read_int(f)
|
|
||||||
if size == 4:
|
if size == 4:
|
||||||
addrfam = socket.AF_INET
|
addrfam = socket.AF_INET
|
||||||
elif size == 16:
|
elif size == 16:
|
||||||
addrfam = socket.AF_INET6
|
addrfam = socket.AF_INET6
|
||||||
else:
|
else:
|
||||||
raise InternalError("bad inet address: %r" % (addrbytes,))
|
raise InternalError("bad inet address: %r" % (addrbytes,))
|
||||||
return (util.inet_ntop(addrfam, addrbytes), port)
|
return util.inet_ntop(addrfam, addrbytes)
|
||||||
|
|
||||||
|
|
||||||
|
def read_inet(f):
|
||||||
|
addr = read_inet_addr_only(f)
|
||||||
|
port = read_int(f)
|
||||||
|
return (addr, port)
|
||||||
|
|
||||||
|
|
||||||
def write_inet(f, addrtuple):
|
def write_inet(f, addrtuple):
|
||||||
|
|||||||
Reference in New Issue
Block a user