Funkyguy
Funkyguy

Reputation: 620

How do I get the method that my exception was raised in?

I have various error checking methods and they are mainly just value or type checking and I want to give the user a chance to fix it so they don't lose a bunch of information regarding what the program is doing.

At this point, I just have this :

def foo(Option1, Option2): 
    if Option1 >= 0 and Option <= 100 :
        continue
    else:
        e = ('Hey this thing doesn\'t work')
        raise ValueError(e)

and then later in the program that is calling it, I have

except ValueError as e:
    print(e)

I want to pass what method was the problem so that I can give the user a chance to try again, like with a prompt or something after right around where the print(e) statement is. Any ideas?

Edit:

Basically I would like my except code to look something like this

except ValueError as e:
    # print the error
    # get what method the error was raised in
    # method = the_method_from_above
    # prompt user for new value
    # send command to the method using the new value

Upvotes: 3

Views: 141

Answers (4)

Aya
Aya

Reputation: 42080

You can do this with some introspection, but you shouldn't.

The following code will let you call the function in which the exception was raised, but there's almost certainly a better way to do whatever it is you're trying to achieve...

import sys

def foo(x):
    print('foo(%r)' % x)
    if not (0 <= x <= 100):
        raise ValueError

def main():
    try:
        foo(-1)
    except ValueError:
        tb = sys.exc_info()[2]
    while tb.tb_next is not None:
        tb = tb.tb_next
    funcname = tb.tb_frame.f_code.co_name
    func = globals()[funcname]
    func(50)

if __name__ == '__main__':
    main()

...which prints out...

foo(-1)
foo(50)

Upvotes: 2

Krumelur
Krumelur

Reputation: 32597

It all very much depends on how the rest of your code looks. There is no simple solution to what you want to achieve. To do that, you have to store not only the function reference, but also the current state of your application. If your program processes information in a loop, you might be able to use something like:

while XXX:
    try:
        o1, o2 = get_user_input_somehow(...)
        foo(o1, o2)
    except ValueError as e:
        print "Error:",e
        print "Please try again"

Upvotes: 1

John Zwinck
John Zwinck

Reputation: 249582

You want what Python calls a traceback. This standard feature lets the receiver of an exception see the call stack from where it was thrown.

Upvotes: 0

Chris
Chris

Reputation: 18032

You can use the traceback module to provide stack trace information about exceptions.

import traceback
...
try:
  pass
except ValueError as e:
  print("Error {0}".format(e))
  traceback.print_exc()

Upvotes: 3

Related Questions