[1.1.4] Global FindFailed handler: how to use in python scripting

Asked by matteoa on 2019-05-17

Hello all,
I'm automating an application that from time to time have a couple of component (not under our control) that crashes with the usual window: "the application pippo.exe has stopped working" and so on.
These crashes appears at random moment, not always in the same phase/window.
The automation script is a state machine that in these cases simply is not able to find the image it was waiting or looking for, so throw exception and exits.

I've ready a sikulix procedure to recover from these cases but I'm not able to call this procedure for any phase it may happen.
I'd like to avoid to put try except for all the images search wait etcetc
There is another way to accomplish this use case?
Thanks in advance
Matteo
P.s. my configuration:
1.1.4-SNAPSHOT-#287-2019-04-18_07:09/Windows10.0/Java8(64)1.8.0_201-b09

Question information

Language:
English Edit question
Status:
Solved
For:
Sikuli Edit question
Assignee:
No assignee Edit question
Solved by:
RaiMan
Solved:
2019-05-24
Last query:
2019-05-24
Last reply:
2019-05-18
RaiMan (raimund-hocke) said : #1

the idea was the FindFailed handler ;-)

... but see your other question:
https://answers.launchpad.net/sikuli/+question/680596

sorry for the delay.

matteoa (matteoa) said : #2

Hello Raiman,
yes, these two questions were related...In case for the findfailed nobody offered the solution I asked for another way to accomplish the same...
Let me add some maybe interesting detail: my script first starts an external VNC app (ultravnc) then takes the application region of the window as ROi for all the subsequent operations.
Just after having created the region vncReg the code is as follows:
appVNC= App(getParentFolder() + r'UltraVNC\vncviewer.exe')
if not appVNC.isRunning(0): appVNC.open(0)
appVNC.focus()
vncReg=appVNC.focusedWindow()
FindFailed.setHandler(HndlFindFailed)
setROI(vncReg.getX(),vncReg.getY(),vncReg.getW(),vncReg.getH())
use() # reset the global SCREEN object to take over the handler setting
Thanks!

Best RaiMan (raimund-hocke) said : #3

looking into the implementation, I have to admit, that is is a mess and does not seem to have been tested in all aspects.

But at least I have fond a solution, that should help you.

This is my example, that worked and sets a global FindFailed handler, that is inherited by all following new Region objects.

again = True

def ffHandler(event):
    global again
    print "From handler: %s" % event
    if again:
        event.setResponse(RETRY)
        again = False
    else:
        event.setResponse(ABORT)

FindFailed("testHandler").setFindFailedHandler(ffHandler)
use() # add the handler to the global SCREEN object
img = "img.png"
find(img)
hover()

The hack is "FindFailed("testHandler")", since setFindFailedHandler() is not implemented as static method.

the constants to be used with event.setResponse in the handler are:
ABORT | SKIP | PROMPT | RETRY (see docs)

Instead of
FindFailed("testHandler").setFindFailedHandler(ffHandler)
use() # add the handler to the global SCREEN object

you could also use
SCREEN.setFindFailedHandler(ffHandler)

If you decide to always use SCREEN as the search region (or a subregion created by setROI())
Hence this will only set a handler for the global SCREEN.

The implementation has to be revised and tested completely. The docs have to be revised too.
Thanks for finding and insisting on a solution ;-)

matteoa (matteoa) said : #4

Thank you Raiman!
no being an experienced Python developer I've always the doubt of being me the problem...
I'll test your solution ASAP.
Let us know the proceedings!

matteoa (matteoa) said : #5

Thanks RaiMan, that solved my question.