I have a relatively complex codebase that has a Decorator to catch exceptions, log them and prevent some boilerplate code. I also have several Services that inherit from a parent BaseService which has methods to access ORM entities. Here's the main points:
def catch_exceptions(return_type, ...):
def _decorator(func):
@wraps(func)
async def async_function(*args, **kwargs):
try:
return await func(*args, **kwargs)
except Exception as e:
_log_exception(func, e, args, kwargs)
return _handle_return(e, return_type, args, kwargs)
@wraps(func)
def sync_function(*args, **kwargs):
#SAME AS async_func but for non async methods
pass
return async_function if inspect.iscoroutinefunction(func) else sync_function
return _decorator
The BaseService has some methods like:
class BaseService:
@classmethod
@catch_exceptions(None)
async def get(cls, ctx:CyContext, id:str=None, **kwargs):
...
#Suppose this throws an exception because ctx.session is missing
item = (await ctx.session.scalars(query.limit(1))).first()
class AppointmentService(BaseService):
pass
If I get an error in this BaseService.get() method, even when it was called from a given previous stacktrace called from AppointmentService, the stacktrace error shows only:
Suppose we use:
async def throw_a():
...
await AppointmentService.get(CyContext(session=None), ...)
...
await throw_a()
Results in:
Traceback (most recent call last):
File "/rest/tools/exceptions.py", line 73, in async_function
return await func(*args, **kwargs)
File "/rest/common/base/services.py", line 188, in get
item = (await ctx.session.scalars(query.limit(1))).first()
AttributeError: 'NoneType' object has no attribute 'scalars'
As if the tree of method calls originated solely on the Wrapper/Decorator, and forcing me to search across all the method calls trying to figure out which one might have sent the incorrect arguments. So the question is: How can I make the decorator be a 'part' of the stacktrace instead of the origin? Or how to print the entire stacktrace including the childmethod call, and it's previous calls?