Bugfix for exceptions

This commit is contained in:
Dirk Alders 2025-02-20 06:53:56 +01:00
parent 7f2b90c990
commit 8ab382dd63

View File

@ -161,13 +161,16 @@ class _callback_storage(dict):
cb_data = self.get(service_id, data_id)
if dict.get(self, service_id, {}).get(data_id, None) is not None:
if callback is None:
self.logger.warning("%s Deleting existing callback %s for service_id (%s) and data_id (%s)!", self.__log_prefix__(), repr(cb_data[0].__name__), repr(service_id), repr(data_id))
del(self[service_id][data_id])
self.logger.warning("%s Deleting existing callback %s for service_id (%s) and data_id (%s)!",
self.__log_prefix__(), repr(cb_data[0].__name__), repr(service_id), repr(data_id))
del (self[service_id][data_id])
return
else:
self.logger.warning("%s Overwriting existing callback %s for service_id (%s) and data_id (%s) to %s!", self.__log_prefix__(), repr(cb_data[0].__name__), repr(service_id), repr(data_id), repr(callback.__name__))
self.logger.warning("%s Overwriting existing callback %s for service_id (%s) and data_id (%s) to %s!",
self.__log_prefix__(), repr(cb_data[0].__name__), repr(service_id), repr(data_id), repr(callback.__name__))
else:
self.logger.debug("%s Adding callback %s for SID=%s and DID=%s", self.__log_prefix__(), repr(callback.__name__), repr(service_id), repr(data_id))
self.logger.debug("%s Adding callback %s for SID=%s and DID=%s", self.__log_prefix__(),
repr(callback.__name__), repr(service_id), repr(data_id))
if service_id not in self:
self[service_id] = {}
self[service_id][data_id] = (callback, args, kwargs)
@ -337,10 +340,8 @@ class pure_json_protocol(object):
self.logger.info('%s Initialisation finished.', self.__log_prefix__())
def __analyse_frame__(self, frame):
if sys.version_info >= (3, 0):
if frame is not None:
return data_storage(json.loads(frame[:-4].decode('utf-8')))
else:
return data_storage(json.loads(frame[:-4]))
def __authentificate_check_key__(self, msg):
key = msg.get_data()
@ -359,10 +360,7 @@ class pure_json_protocol(object):
def __authentificate_create_seed__(self, msg):
self.__authentification_state__ = AUTH_STATE_SEED_TRANSFERRED
if sys.version_info >= (3, 0):
self.__seed__ = binascii.hexlify(os.urandom(32)).decode('utf-8')
else:
self.__seed__ = binascii.hexlify(os.urandom(32))
self.__seed__ = binascii.hexlify(os.urandom(32)).decode('utf-8')
return STATUS_OKAY, self.__seed__
def __authentificate_process_feedback__(self, msg):
@ -376,10 +374,7 @@ class pure_json_protocol(object):
return STATUS_OKAY, None
def __authentificate_salt_and_hash__(self, seed):
if sys.version_info >= (3, 0):
return hashlib.sha512(bytes(seed, 'utf-8') + self.__secret__).hexdigest()
else:
return hashlib.sha512(seed.encode('utf-8') + self.__secret__.encode('utf-8')).hexdigest()
return hashlib.sha512(bytes(seed, 'utf-8') + self.__secret__).hexdigest()
def __authentification_state_reset__(self):
self.logger.info("%s Resetting authentification state to AUTH_STATE_UNTRUSTED_CONNECTION", self.__log_prefix__())
@ -398,8 +393,7 @@ class pure_json_protocol(object):
def __build_frame__(self, msg):
data_frame = json.dumps(self.__mk_msg__(msg.get_status(), msg.get_service_id(), msg.get_data_id(), msg.get_data()))
if sys.version_info >= (3, 0):
data_frame = bytes(data_frame, 'utf-8')
data_frame = bytes(data_frame, 'utf-8')
checksum = self.__calc_chksum__(data_frame)
return data_frame + checksum
@ -427,7 +421,8 @@ class pure_json_protocol(object):
prev_channel_name = self.__channel_name__
self.__init_channel_name__(data)
if prev_channel_name is not None and prev_channel_name != data:
self.logger.warning('%s overwriting user defined channel name from %s to %s', self.__log_prefix__(), repr(prev_channel_name), repr(data))
self.logger.warning('%s overwriting user defined channel name from %s to %s',
self.__log_prefix__(), repr(prev_channel_name), repr(data))
elif prev_channel_name is None:
self.logger.info('%s channel name is now %s', self.__log_prefix__(), repr(self.__channel_name__))
return STATUS_OKAY, None
@ -462,17 +457,20 @@ class pure_json_protocol(object):
msg = self.__analyse_frame__(frame)
if not self.__check_frame_checksum__(frame):
# Wrong Checksum
self.logger.log(self.__status_log_lvl__(STATUS_CHECKSUM_ERROR), "%s Received message has an invalid checksum. Message will be ignored.", self.__log_prefix__())
self.logger.log(self.__status_log_lvl__(STATUS_CHECKSUM_ERROR),
"%s Received message has an invalid checksum. Message will be ignored.", self.__log_prefix__())
return # No response needed
elif not self.check_authentification_state() and self.__authentification_required__(msg.get_service_id(), msg.get_data_id()):
# Authentification required
self.__log_msg__(msg, 'RX <-')
if msg.get_service_id() in self.__sid_response_dict__.keys():
self.logger.log(self.__status_log_lvl__(STATUS_AUTH_REQUIRED), "%s Authentification is required. Just sending negative response.", self.__log_prefix__())
self.logger.log(self.__status_log_lvl__(STATUS_AUTH_REQUIRED),
"%s Authentification is required. Just sending negative response.", self.__log_prefix__())
status = STATUS_AUTH_REQUIRED
data = None
else:
self.logger.log(self.__status_log_lvl__(STATUS_AUTH_REQUIRED), "%s Authentification is required. Incomming message will be ignored.", self.__log_prefix__())
self.logger.log(self.__status_log_lvl__(STATUS_AUTH_REQUIRED),
"%s Authentification is required. Incomming message will be ignored.", self.__log_prefix__())
return # No response needed
else:
# Valid message
@ -491,7 +489,8 @@ class pure_json_protocol(object):
try:
status, data = callback(msg, *args, **kwargs)
except Exception as e:
self.logger.error('{lp} Exception raised. Check callback {callback_name}: "{message}" and it\'s return values for {msg_info}'.format(lp=self.__log_prefix__(), callback_name=callback.__name__, message=str(e), msg_info=self.__get_message_name__(msg.get_service_id(), msg.get_data_id())))
self.logger.error('{lp} Exception raised. Check callback {callback_name}: "{message}" and it\'s return values for {msg_info}'.format(
lp=self.__log_prefix__(), callback_name=callback.__name__, message=str(e), msg_info=self.__get_message_name__(msg.get_service_id(), msg.get_data_id())))
status = STATUS_CALLBACK_ERROR
data = None
else:
@ -505,7 +504,8 @@ class pure_json_protocol(object):
try:
callback(msg, *args, **kwargs)
except Exception as e:
self.logger.error('{lp} Exception raised. Check callback {callback_name}: "{message}" for {msg_info}'.format(lp=self.__log_prefix__(), callback_name=callback.__name__, message=str(e), msg_info=self.__get_message_name__(msg.get_service_id(), msg.get_data_id())))
self.logger.error('{lp} Exception raised. Check callback {callback_name}: "{message}" for {msg_info}'.format(lp=self.__log_prefix__(
), callback_name=callback.__name__, message=str(e), msg_info=self.__get_message_name__(msg.get_service_id(), msg.get_data_id())))
return # No response needed
self.send(self.__sid_response_dict__[msg.get_service_id()], msg.get_data_id(), data, status=status)
@ -568,7 +568,8 @@ class pure_json_protocol(object):
if service_id not in self.__auth_whitelist__:
self.__auth_whitelist__[service_id] = []
self.__auth_whitelist__[service_id].append(data_id)
self.logger.debug('%s Adding Message (%s) to the authentification whitelist', self.__log_prefix__(), self.__get_message_name__(service_id, data_id))
self.logger.debug('%s Adding Message (%s) to the authentification whitelist',
self.__log_prefix__(), self.__get_message_name__(service_id, data_id))
def add_service(self, req_sid, resp_sid, req_name=None, resp_name=None):
"""
@ -580,10 +581,12 @@ class pure_json_protocol(object):
:type resp_sid: int
"""
if req_sid in self.__sid_response_dict__:
self.logger.error('%s Service with Request-SID=%d and Response-SID=%d not added, because request SID is already registered', self.__log_prefix__(), req_sid, resp_sid)
self.logger.error('%s Service with Request-SID=%d and Response-SID=%d not added, because request SID is already registered',
self.__log_prefix__(), req_sid, resp_sid)
raise RequestSidExistsError("Request for this Service is already registered")
elif resp_sid in self.__sid_response_dict__.values():
self.logger.error('%s Service with Request-SID=%d and Response-SID=%d not added, because response SID is already registered', self.__log_prefix__(), req_sid, resp_sid)
self.logger.error('%s Service with Request-SID=%d and Response-SID=%d not added, because response SID is already registered',
self.__log_prefix__(), req_sid, resp_sid)
raise ResponseSidExistsError("Response for this Service is already registered")
else:
self.__sid_response_dict__[req_sid] = resp_sid
@ -591,7 +594,8 @@ class pure_json_protocol(object):
self.__sid_name_dict__[req_sid] = req_name
if resp_name is not None:
self.__sid_name_dict__[resp_sid] = resp_name
self.logger.debug('%s Adding Service with Request=%s and Response=%s', self.__log_prefix__(), req_name or repr(req_sid), resp_name or repr(resp_sid))
self.logger.debug('%s Adding Service with Request=%s and Response=%s', self.__log_prefix__(),
req_name or repr(req_sid), resp_name or repr(resp_sid))
def add_status(self, status, name):
"""
@ -680,7 +684,8 @@ class pure_json_protocol(object):
cnt += 1
time.sleep(0.1)
if data is None and cnt >= timeout * 10:
self.logger.warning('%s TIMEOUT (%ss): Requested data (service_id: %s; data_id: %s) not in buffer.', self.__log_prefix__(), repr(timeout), repr(service_id), repr(data_id))
self.logger.warning('%s TIMEOUT (%ss): Requested data (service_id: %s; data_id: %s) not in buffer.',
self.__log_prefix__(), repr(timeout), repr(service_id), repr(data_id))
return data
def reconnect(self):
@ -748,7 +753,8 @@ class pure_json_protocol(object):
return self.__comm_inst__.send(self.__build_frame__(msg), timeout=timeout)
else:
# Authentification required
self.logger.warning("%s Authentification is required. TX-Message %s, %s, data: %s will be ignored.", self.__log_prefix__(), self.__get_message_name__(service_id, data_id), self.__get_status_name__(status), repr(data))
self.logger.warning("%s Authentification is required. TX-Message %s, %s, data: %s will be ignored.", self.__log_prefix__(),
self.__get_message_name__(service_id, data_id), self.__get_status_name__(status), repr(data))
return False
@ -760,38 +766,26 @@ class struct_json_protocol(pure_json_protocol):
.. note::
This class is depreceated and here for compatibility reasons (to support old clients or servers). Usage of :class:`pure_json_protocol` is recommended.
"""
def __init__(self, *args, **kwargs):
pure_json_protocol.__init__(self, *args, **kwargs)
def __analyse_frame__(self, frame):
status, service_id, data_id = struct.unpack('>III', frame[0:12])
if sys.version_info >= (3, 0):
data = json.loads(frame[12:-1].decode('utf-8'))
else:
data = json.loads(frame[12:-1])
data = json.loads(frame[12:-1].decode('utf-8'))
return self.__mk_msg__(status, service_id, data_id, data)
def __build_frame__(self, msg):
frame = struct.pack('>III', msg.get_status(), msg.get_service_id(), msg.get_data_id())
if sys.version_info >= (3, 0):
frame += bytes(json.dumps(msg.get_data()), 'utf-8')
frame += self.__calc_chksum__(frame)
else:
frame += json.dumps(msg.get_data())
frame += self.__calc_chksum__(frame)
frame += bytes(json.dumps(msg.get_data()), 'utf-8')
frame += self.__calc_chksum__(frame)
return frame
def __calc_chksum__(self, raw_data):
chksum = 0
for b in raw_data:
if sys.version_info >= (3, 0):
chksum ^= b
else:
chksum ^= ord(b)
if sys.version_info >= (3, 0):
return bytes([chksum])
else:
return chr(chksum)
chksum ^= b
return bytes([chksum])
def __check_frame_checksum__(self, frame):
return self.__calc_chksum__(frame[:-1]) == frame[-1:]