[HowTo] User defined exceptions to handle FindFailed

Asked by Calle Rundgren

Hi!

I want to define my own exception, is that possible? I have been reading through some python and jython documentation but would not be able to get it.

I know that i should define a exception as a class, like this:

class MyException(Exception):
    def __init__(self)
    +some more code

But how would be the best way to continue if I want to get my exception to work as the FindFailed exception?

The reason I would like to use user defined excetions is that I would run a script where several images could be either be there or not. And I want to do different things according on what exception who is raised. Probably I could use the FindFailed exception, but then what to do when several exceptions is raised and everybody is refered to as find failed?

Question information

Language:
English Edit question
Status:
Solved
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Solved by:
RaiMan
Solved:
Last query:
Last reply:
Revision history for this message
Best RaiMan (raimund-hocke) said :
#1

I think I know the history of your problem/challenge.

Defining your own exception does not really help, since I think you want to connect the "not found" situation with a specific object, that is not found.

So you have a 1-1 relation a -> b, that says if a not found, then do b.

In your case, a is some image or pattern object and b is some piece of code to be run, if a is not found.

This is normally done with (I know you know that ;-)

if not exists():
   pass # handling if not found
else:
   pass # handling if found

this could be packed into a def(), so your code gets leaner:

a basic example (working on the whole screen):

def myCheck(img, msg=None):
    if not exists(img): # img might be an image filename, pattern object or text
        if not msg:
             print("<%s> could not be found"%(img))
             return None
        else:
             popup(msg)
             exit()
        return None
    return getLastMatch()

theMatch = myCheck("some-img.png")
click theMatch # does nothing if not found, script continues

or

theMatch = myCheck("some-img.png", "this is a show stopper")
popup("script continues") # will not popup, if not found

so you could pack all needed actions into myCheck() and control the effects with parameters as you like.

a more general approach could use a dictionary, that maps the object to a handler, so you need some register function to manage your dictionary.

a basic example:

d = {} # the dictionary

def xH(): # should be processed for x
    print "i am handler xH"

def yH(): # should be processed for y
    print "i am handler yH"

# now we "register" relations
x = "some-image.png"
d[x] = xH # for x, handler xH should be processed

y = Pattern(x)
d[y] = yH # for y, handler yH should be processed

print d # show our repository

d[x]() # run the action for x
d[y]() # run the action for y

hope it helps ;-)

Revision history for this message
Calle Rundgren (c-rundgren) said :
#2

Thank you, I will test this solution. And thanks for the part with the dictionary. I will try to get both solutions to work as I want to. :)

But is there any solution for defining a exception to work as FindFailed. I do not think I would use it cause your solution would probably do what I want. I just would think it is nice to know. :)

Revision history for this message
Calle Rundgren (c-rundgren) said :
#3

Thanks RaiMan, that solved my question.

Revision history for this message
RaiMan (raimund-hocke) said :
#4

--- ok, here you are ;-)
*** User defined exceptions in Sikuli scripts (Python/Jython)

the basic template is:

class MyException(Exception):
    def __init__(self):
        pass
    def __str__(self):
        # this string complements an error message
        return "This is my own Exception"

usage in your code:

raise MyException()

You will get the standard traceback with the last line as
__main__.MyException: This is my own Exception

or handled:

try:
   if some_condition: raise MyException()
except MyException:
   print "we had MyException"
   exit()

you might have to additionally handle the traceback information and/or sys.exc as normally with try: except:

So the above situation could be handled with your own exception as well
(but I think in a Sikuli script any FindFailed exception handling looks much more ugly then using exists()):

def handler():
    print "I am the handler for FindFailed"
    return "some information"

class MyException(Exception):
    def __init__(self, handler):
        self.status = handler()
    def __str__(self):
        # this string complements an error message
        return "We handled a FindFailed exception"

if not exists("some-image.png"): raise MyException(handler)

and with try: except:

try:
   if not exists("some-image.png"): raise MyException(handler)
except MyException, e:
   print "we made it:", e.status

Revision history for this message
Calle Rundgren (c-rundgren) said :
#5

Thank you. Now I can play around with this for a while :)