How to catch an exception in a decorator

python, python-decorators

Solution

As the other answers have explained, your current issue is that you're getting the exception raised when the decorator is applied to the function, not when the function is called.

To fix this, you need to make the decorator return a function that does the exception raising. Here's how that could work:

import functools

def des(i):
    def decorator(func):
        if i != 1:
            return func # no wrapper needed

        @functools.wraps(func)
        def raiser(*args, **kwargs):
            raise Exception

        return raiser

    return decorator

The `des` function is a "decorator factory". It doesn't really doesn't do anything other than providing a scope to hold the `i` parameter for the decorator that it returns.

The `decorator` function does the check to see if anything special needs to be done. If not, it returns the decorated function unmodified. If `i==1`, it returns a custom function.

The `raiser` function is the decorator's return value if `i==1`. It always raises an exception when it is called. The `functools.wraps` decorator applied to it is not strictly necessary, but it makes it look more like the original function (same `__name__`, `__doc__`, etc).

Problem

I have a function my cause exception and i want it to be a decorator. The code is as follow: ``` def des(i): def new_func(func): if i == 1: raise Exception else: return func return new_func @des(1) def func(): print "!!" if __name__ == '__main__': try: func() except Exception: print 'error' ``` but the output is: ``` Traceback (most recent call last): File "D:/des.py", line 10, in <module> @des(1) File "D:/des.py", line 4, in new_func raise Exception Exception ``` so, how can I catch this exception?

Original source

Related problems