Home > OS >  Exceptions: How to display which function caused the exception?
Exceptions: How to display which function caused the exception?

Time:01-05

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}()")
  •  Tags:  
  • Related