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:
Chris
i get an unhandled exception in the callback and the device process which executed the command exits.

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()

6. 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 :)

Regards,
Chris
 
Register or login to create to post a reply.