Exceptions with asynchronous command calls

dear all,

I am currently trying to implement a Tango device in Python which uses asynchronous command calls (with the PUSH model) to other Tango Devices. The devices on which the commands are implemented have the “is_XX_allowed” method so certain commands cannot be called from certain states. This works well with synchronous calls, however, I cannot seem to catch the exception that is thrown when I use an asynchronous call to try to execute a command from a non-allowed state. If I try to execute a command on a device that is in a non-allowed state for that command, i get an unhandled exception in the callback and the device process which executed the command exits.

The device which calls the asynchronous commands has a callback which looks like the following:


    def deviceOnCallback(self, event):
        try:
            if not event.err:
                self.deviceWaiting -=1
                apiutil = PyTango.ApiUtil.instance()
                self.semaphore.release()
            else:
                self.error_stream(event.errors)
        except:
            self.error_stream("exception in callback: " + str(sys.exc_info()))

and calls the command in the following way:


    self.tractorDev.command_inout_asynch("On", self.deviceOnCallback)

the device whos command is being called has the following


    def is_On_allowed(self):
        return self.get_state() == DevState.OFF

Forgive me if this is a simple problem, but I was hoping someone might be able to assist in the correct way to handle exceptions in this case.

Regards,
Chris

Hi Chris,

I am not sure I understand what you mean by:

In the callback you should get an event with the err member flag set to True.
The errors member is a sequence of DevError representing the error stack that occurred on the server.

I ask that you test the two servers in attachment.

  1. with jive configure D1/test server with a device of class D1.

  2. with jive configure D2/test server with a device of class D2.
    2.1 add a property to D2 device called “d1_name” and fill it with the name of the D1 device

  3. start first server with: python D1.py test

  4. start second server with: python D2.py test

  5. in a python shell do:

>>> import PyTango
>>> d2 = PyTango.DeviceProxy( <name of your D2 device> )
>>> d2.do_it()

  1. in the console of the D2 server you should see an output like this:
~/tmp/forum_topic80$ python D2.py test
Failed to import EventChannelFactory notifd/factory/bcu01ctrl.esrf.fr from the Tango database
Ready to accept request
error in cmd
Tango exception
Severity = ERROR 
Error reason = API_CommandNotAllowed
Desc : Command go not allowed when the device is in UNKNOWN state
Origin : DeviceClass::command_handler

Tango exception
Severity = ERROR 
Error reason = API_CommandFailed
Desc : Failed to execute command_inout_asynch on device test/d1/1, command go
Origin : Connection::Cb_Cmd_Request()

Can you confirm this is what you get?

Hi Tiago,

Thanks for the response, your examples helped a lot. I didn’t know where to do any error handling as I didn’t realise that the error came through in the event like that. Now that I can do some error handling in the callback my devices work fine :slight_smile:

Regards,
Chris