I have a code block that looks like:
try:
if x == 1:
a()
if x == 2:
b()
if x == 3:
c()
except Exception:
raise Exception("Problem in function")
Each of the functions a(), b()and c() are capable of having exceptions. Is there anyway I can raise an exception with a message that tells which function caused the exception.
I want to know if its possible here without using try, catch statements inside each of these functions separately.
CodePudding user response:
The first thing I would think of is to try something like this:
try:
if x == 1:
a()
if x == 2:
b()
if x == 3:
c()
except Exception:
raise Exception("Problem in function, x=%s"%x)
Now, when the exception is raised, you can see what the value of x was.
For something more detailed, perhaps something like this:
try:
if x == 1:
flabel = 'func_a'
a()
if x == 2:
flabel = 'func_b'
b()
if x == 3:
flable = 'func_c'
c()
except Exception:
raise Exception("Problem in function %s"%flabel)
CodePudding user response:
This is probably too specific to your example, but I would in general try to refactor the code and make a specific note of which function is going to be executed.
if x == 1:
func_name = "a"
func = a
elif x == 2:
func_name = "b"
func = b
elif x == 3:
func_name = "c"
func = c
try:
func()
except Exception:
raise Exception(f"Problem in {func_name}")
You may be able to get rid of func_name and use func.__name__ instead, as long as all three functions are being referred by their "original" name.
CodePudding user response:
You can try
import traceback
try:
if x == 1:
a()
if x == 2:
b()
if x == 3:
c()
except Exception as excp:
stack = traceback.extract_stack()[:-3] traceback.extract_tb(excp.__traceback__)
(filename, line, procname, text) = stack[-1]
print (f" func {procname}")#
raise Exception("Problem in function")
CodePudding user response:
You could define a decorator function that wrapped the other so the information needed was available (this is a variation of @chepner's answer):
def decorator(func):
wraps(func)
def wrapper(*args, **kwargs):
global func_name
func_name = func.__name__
return func(*args, **kwargs)
return wrapper
@decorator
def a():
pass
@decorator
def b():
raise RuntimeError('Uh Oh!')
@decorator
def a():
pass
x = 2
try:
if x == 1:
a()
if x == 2:
b()
if x == 3:
c()
except Exception as exc:
raise Exception(f"Problem in function {func_name}()")
