From 58ac291f9ffee4efa57f154f1f3e7172268a84c0 Mon Sep 17 00:00:00 2001 From: yshepilov Date: Sat, 18 Mar 2023 16:08:44 +0100 Subject: [PATCH] #320 fixed missing observable notifications in case of an exception + fixed swallowing a websocket future exception --- src/model/script_config.py | 1 - src/react/properties.py | 16 +++++++++++----- src/web/script_config_socket.py | 11 +++++++++-- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/model/script_config.py b/src/model/script_config.py index 507c493e..8f854db5 100644 --- a/src/model/script_config.py +++ b/src/model/script_config.py @@ -1,5 +1,4 @@ import logging -import logging import os from collections import OrderedDict from dataclasses import dataclass, field diff --git a/src/react/properties.py b/src/react/properties.py index acfe79c4..398447fd 100644 --- a/src/react/properties.py +++ b/src/react/properties.py @@ -1,11 +1,13 @@ +import logging from collections import UserList, UserDict - from typing import Optional, Iterable as Iterable, Mapping as Mapping, TypeVar _T = TypeVar('_T') _KT = TypeVar('_KT') _VT = TypeVar('_VT') +LOGGER = logging.getLogger('script_server.properties') + class Property: def __init__(self, value=None): @@ -152,9 +154,7 @@ def __setitem__(self, key: _KT, item: _VT) -> None: super().__setitem__(key, item) - if self._observers: - for observer in self._observers: - observer(key, old_value, item) + self._notify_observers(key, old_value, item) def __delitem__(self, key: _KT) -> None: old_value = self.get(key) @@ -164,9 +164,15 @@ def __delitem__(self, key: _KT) -> None: if old_value is None: return + self._notify_observers(key, old_value, None) + + def _notify_observers(self, key, old_value, new_value): if self._observers: for observer in self._observers: - observer(key, old_value, None) + try: + observer(key, old_value, new_value) + except: + LOGGER.exception('Failed to notify observer ' + repr(observer)) def observable_fields(*fields): diff --git a/src/web/script_config_socket.py b/src/web/script_config_socket.py index c742405a..691a5058 100644 --- a/src/web/script_config_socket.py +++ b/src/web/script_config_socket.py @@ -70,13 +70,20 @@ def on_message(self, text): data = message.get('data') if type == 'parameterValue': + param = data.get('parameter') set_parameter_func = functools.partial( self._set_parameter_value, - data.get('parameter'), + param, data.get('value'), data.get('clientStateVersion')) - self._start_task(set_parameter_func) + def handle_future_exception(result): + if result.exception(): + LOGGER.exception(f'Failed to set parameter {param} value', exc_info=result.exception()) + + future = self._start_task(set_parameter_func) + future.add_done_callback(handle_future_exception) + return elif type == 'reloadModelValues': parameter_values = data.get('parameterValues')