DeviceProxy async methods inconsistency (should return error)
Hello,
I was working on this PyTango issue: pytango#590 (closed)
so I investigated different behaviour of *_async
methods with callback in PUSH_CALLBACK
model and there seems to be inconsistency.
When I throw an exception inside a command, my callback receives event with err
property set to True
(like expected).
But when I throw exception in the attribute, the callback passed to read_attribute_asynch
receives event with err
property set to False, just like nothing wrong happened.
Here's a demonstration written in PyTango, but the same applies to CppTango where it originates:
import time
import tango
from tango.server import command, Device, attribute
from tango.test_utils import DeviceTestContext
from concurrent.futures import Future
class ServerForAsynchClients(Device):
@command(dtype_in=int, dtype_out=int)
def cmd_timeout(self, arg):
time.sleep(2)
return arg
@command(dtype_in=int, dtype_out=int)
def cmd_exception(self, arg):
raise Exception("Intentional exception")
@attribute(dtype=int)
def attr_timeout(self):
time.sleep(2)
return 123
@attribute(dtype=int)
def attr_exception(self):
raise Exception("Intentional exception")
with DeviceTestContext(ServerForAsynchClients, process=True) as proxy:
tango.ApiUtil.instance().set_asynch_cb_sub_model(tango.cb_sub_model.PUSH_CALLBACK)
proxy.set_timeout_millis(1000)
# Command with exception returns error to callback
future = Future()
proxy.command_inout_asynch("cmd_exception", 123, future.set_result)
result = future.result(timeout=5)
assert result.err == True
# Command with timeout returns error to callback
future = Future()
proxy.command_inout_asynch("cmd_timeout", 123, future.set_result)
result = future.result(timeout=5)
assert result.err == True
# Read attribute with exception DOESN'T indicate error to callback (but probably should?)
future = Future()
proxy.read_attribute_asynch("attr_exception", future.set_result)
result = future.result(timeout=5)
assert result.err == False # This should fail, but it doesn't
assert result.argout[0].has_failed == True # Instead we get report like this.
# Read attribute with timeout fails for PyTango completely
# But with CppTango client it works and returns error to callback
# After fixing this part, so it don't crash, the result.err is set to True (consistently with command_inout_asynch)
# future = Future()
# proxy.read_attribute_asynch("attr_timeout", future.set_result)
# result = future.result(timeout=5)
# assert result.err == True
Edited by Mateusz C