an error on a write must not send an error update

Change-Id: I07a991bcf26e87121160a2e604f8842eba23ebaf
Reviewed-on: https://forge.frm2.tum.de/review/c/secop/frappy/+/35281
Tested-by: Jenkins Automated Tests <pedersen+jenkins@frm2.tum.de>
Reviewed-by: Markus Zolliker <markus.zolliker@psi.ch>
This commit is contained in:
zolliker 2024-12-09 14:31:31 +01:00
parent bdb14af4af
commit 6da671df62
2 changed files with 37 additions and 6 deletions

View File

@ -188,10 +188,8 @@ class HasAccessibles(HasProperties):
if new_value is Done: # TODO: to be removed when all code using Done is updated if new_value is Done: # TODO: to be removed when all code using Done is updated
return getattr(self, pname) return getattr(self, pname)
new_value = value if new_value is None else validate(new_value) new_value = value if new_value is None else validate(new_value)
except Exception as e: except SECoPError as e:
if isinstance(e, SECoPError): e.raising_methods.append(f'{self.name}.write_{pname}')
e.raising_methods.append(f'{self.name}.write_{pname}')
self.announceUpdate(pname, err=e)
raise raise
self.announceUpdate(pname, new_value, validate=False) self.announceUpdate(pname, new_value, validate=False)
return new_value return new_value
@ -516,13 +514,13 @@ class Module(HasAccessibles):
with self.updateLock: with self.updateLock:
pobj = self.parameters[pname] pobj = self.parameters[pname]
timestamp = timestamp or time.time() timestamp = timestamp or time.time()
changed = False
if not err: if not err:
try: try:
if validate: if validate:
value = pobj.datatype(value) value = pobj.datatype(value)
except Exception as e: except Exception as e:
err = e err = e
changed = False
else: else:
changed = pobj.value != value or pobj.readerror changed = pobj.value != value or pobj.readerror
# store the value even in case of error # store the value even in case of error

View File

@ -28,7 +28,7 @@ from glob import glob
import pytest import pytest
from frappy.datatypes import BoolType, FloatRange, StringType, IntRange, ScaledInteger from frappy.datatypes import BoolType, FloatRange, StringType, IntRange, ScaledInteger
from frappy.errors import ProgrammingError, ConfigError, RangeError from frappy.errors import ProgrammingError, ConfigError, RangeError, HardwareError
from frappy.modules import Communicator, Drivable, Readable, Module, Writable from frappy.modules import Communicator, Drivable, Readable, Module, Writable
from frappy.params import Command, Parameter, Limit from frappy.params import Command, Parameter, Limit
from frappy.rwhandler import ReadHandler, WriteHandler, nopoll from frappy.rwhandler import ReadHandler, WriteHandler, nopoll
@ -941,3 +941,36 @@ def test_stop_doc(modcls):
if (modcls.stop.description == Drivable.stop.description if (modcls.stop.description == Drivable.stop.description
and modcls.stop.func != Drivable.stop.func): and modcls.stop.func != Drivable.stop.func):
assert modcls.stop.func.__doc__ # stop method needs a doc string assert modcls.stop.func.__doc__ # stop method needs a doc string
def test_write_error():
updates = {}
srv = ServerStub(updates)
class Mod(Module):
par = Parameter('', FloatRange(), readonly=False, default=0)
def read_par(self):
raise HardwareError('failure')
def write_par(self, value):
if value < 0:
raise RangeError('outside range')
a = Mod('a', LoggerStub(), {'description': 'test'}, srv)
# behaviour on read errors:
with pytest.raises(HardwareError):
a.read_par()
assert updates == {'a': {('error', 'par'): 'failure'}}
updates.clear()
# behaviour on normal write
a.write_par(1)
assert updates['a']['par'] == 1
updates.clear()
# behaviour when write failed
with pytest.raises(RangeError):
a.write_par(-1)
assert not updates # no error update!