Try/Catch Decorator
Try - Catch
Published: December 2020
Exception Handling on Multiple Functions
I often find myself splitting my code across modules each with their functions that I use in some sort of a main
script or function for my projects. I like to log the progress of my code when it is deployed and I also like to keep one single log per project (when this makes sense obviously). When a function I imported is being used by the main function/script, I try to wrap it in some try/except (see below code block) block to make sure I catch any unexpected failure.
try:
# call the function
except:
# do something and log it
finally:
# release resources
In the spirit of DRY, I started using this simple decorator for my functions so that I can avoid wrapping all functions with the try/except block.
The Snippet
from functools import wraps
from loguru._logger import Logger
def try_catch(logger: Logger):
"""
Decorate a function with the module logger to not just track errors
but catch errors on any function without repeating a try:...except:... block
:param logger: a logger object, could be a python native logger as well
"""
def proper_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
try:
output = func(*args, **kwargs)
return output
except Exception as e:
logger.exception(f"Failure in {func.__name__}")
raise e
return wrapper
return proper_decorator
I use the wraps
decorator from functools
so that I can use the function's actual name in my traceback.
An Example
from loguru import logger
# set the logger handle etc. here
@try_catch(logger)
def my_function(numpy_array, user_constant):
"""
Just a 1-D Numpy arrays divided by some constant.
P.S. this example is designed to fail with constant 0
i.e. I omit the ZeroDivision check
"""
reciprocal = 1 / user_constant
return reciprocal * numpy_array
# try
import numpy as np
my_function(np.array([0, 1]), 2)
my_function(np.array([0, 1]), 0) # Inspect the log and traceback
When my_function
fails with user providing 0
for the constant, I want to see the full traceback and the decorator handles that.
I would suggest using this for functions dealing with databases or external communication that can easily fail unexpectedly.
Thank you!