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
return getattr(self, pname)
new_value = value if new_value is None else validate(new_value)
except Exception as e:
if isinstance(e, SECoPError):
e.raising_methods.append(f'{self.name}.write_{pname}')
self.announceUpdate(pname, err=e)
except SECoPError as e:
e.raising_methods.append(f'{self.name}.write_{pname}')
raise
self.announceUpdate(pname, new_value, validate=False)
return new_value
@ -516,13 +514,13 @@ class Module(HasAccessibles):
with self.updateLock:
pobj = self.parameters[pname]
timestamp = timestamp or time.time()
changed = False
if not err:
try:
if validate:
value = pobj.datatype(value)
except Exception as e:
err = e
changed = False
else:
changed = pobj.value != value or pobj.readerror
# store the value even in case of error

View File

@ -28,7 +28,7 @@ from glob import glob
import pytest
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.params import Command, Parameter, Limit
from frappy.rwhandler import ReadHandler, WriteHandler, nopoll
@ -941,3 +941,36 @@ def test_stop_doc(modcls):
if (modcls.stop.description == Drivable.stop.description
and modcls.stop.func != Drivable.stop.func):
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!