Nipun Wijerathne
Nipun Wijerathne

Reputation: 1829

Catching exception inside a decorator

This questions may not be correct theoretically but would like to know if there is any workaround.

Let's consider the following example:

def my_function():
    try:
        print("before the exception occurs")
        raise ValueError
    except ValueError:
        print('exception found')

    print("after the exception occurs")


if __name__ == "__main__":
    my_function()

if you print to stdout, the output should be as follows:

before the exception occurs
exception found
after the exception occurs

However, if you use a decorator to catch the exception as below:

from functools import wraps


def decorator(func):
  @wraps(func)
  def wrapper(*args, **kwargs):
    try:
        return func(*args, **kwargs)
    except ValueError:
        print('exception found')

  return wrapper


@decorator
def my_exception_function():
  print("before the exception occurs")

  raise ValueError

  print("after the exception occurs")


if __name__ == "__main__":
  my_exception_function()

the rest of the function after the exception occurs will not be executed as below:

before the exception occurs
exception found

Therefore, I would like to know if there any workaround that I can use to get the first example output but using a decorator to catch the exception.

Upvotes: 0

Views: 2245

Answers (1)

rdas
rdas

Reputation: 21275

Let's try to inline the my_exception_func inside the decorator.

from functools import wraps


def decorator(func):
  @wraps(func)
  def wrapper(*args, **kwargs):
    try:
        print("before the exception occurs")
        raise ValueError
        print("after the exception occurs")
    except ValueError:
        print('exception found')

  return wrapper

So now the control flow should be more clear:

  • Print 'before the exception'
  • Exception raised
  • Go to the except block
  • return

Due to the exception, the 'after exception' print is never reached.

Using a try-except block to catch the exception, but then executing the code after the point of exception doesn't really work. You'll need to isolate exactly where the exception might happen and wrap only that part in the try-except block.

Upvotes: 3

Related Questions