Extending the answer from @simon i end up tracking all the traceback returning by extract_tb().
Package:
from logging import getLogger
from os.path import basename
from traceback import extract_tb
logSys = getLogger()
def catchUnexpectedError(funct):
def wrapper():
try:
funct()
except Exception as unknown:
stack = extract_tb(unknown.__traceback__)
exc, msg = repr(unknown).rstrip(')').split('(', maxsplit=1)
logSys.critical(f'Execution finished by exception {exc}: {msg.strip(chr(34))}.')
logSys.critical(f'The following errors led to program failure:')
for n, tb in enumerate(stack):
logSys.error(f'{n}) {tb.line} (line {tb.lineno}) at {basename(tb.filename)}')
return wrapper
Module:
from asset import catchUnexpectedError
def nested():
raise ValueError("Deliberately raise")
@catchUnexpectedError
def hello():
nested()
hello()
Output:
[CRITICAL] Execution finished by exception ValueError: 'Deliberately raise'. (11:27:43 29/10/2025)
[CRITICAL] The following errors led to program exit: (11:27:43 29/10/2025)
[ERROR] 0) funct() (line 51) at _init_.py (11:27:43 29/10/2025)
[ERROR] 1) nested() (line 15) at main.py (11:27:43 29/10/2025)
[ERROR] 2) raise ValueError("Deliberately raise") (line 11) at main.py (11:27:43 29/10/2025)