timeout-decorator icon indicating copy to clipboard operation
timeout-decorator copied to clipboard

Incorrent traceback

Open delphikettle opened this issue 7 years ago • 2 comments

When an Exception occurs in decorated method, it is not possible to see the real traceback. For example:

import traceback

from timeout_decorator import timeout_decorator


@timeout_decorator.timeout(10, use_signals=False)
def func():
    raise Exception('Somethind went wrong')


try:
    func()
except:
    print(traceback.format_exc())

prints

Traceback (most recent call last): File "/home/dk/Share/test.py", line 11, in func() File "/home/dk/.pyenv/versions/das/lib/python3.5/site-packages/timeout_decorator/timeout_decorator.py", line 91, in new_function return timeout_wrapper(*args, **kwargs) File "/home/dk/.pyenv/versions/das/lib/python3.5/site-packages/timeout_decorator/timeout_decorator.py", line 150, in call return self.value File "/home/dk/.pyenv/versions/das/lib/python3.5/site-packages/timeout_decorator/timeout_decorator.py", line 173, in value raise load Exception: Somethind went wrong

It only happens when use_signals is set to False.

delphikettle avatar May 06 '18 12:05 delphikettle

This is the code that passes exception value: https://github.com/pnpnpn/timeout-decorator/blob/master/timeout_decorator/timeout_decorator.py#L108

Try passing both value (exc_info()[1]) and traceback (exc_info()[2]) there. Print traceback info with an appropriate function traceback.print_tb.

paboldin avatar May 06 '18 18:05 paboldin

Attempting to pass the traceback directly from the background process won't work, as tracebacks can't be serialised with the pickle module by default. If that wasn't the case, the multiprocessing module would be able to correctly preserve the __traceback__ attribute on the exception instance itself.

This SO answer covers one way to handle the situation: https://stackoverflow.com/questions/6126007/python-getting-a-traceback-from-a-multiprocessing-process

That specific solution (enabling tblib's pickling support) wouldn't be appropriate for library like timeout decorator, but the to_dict and from_dict methods would allow at least the top level traceback to be passed back to the foreground process in a way that could then be used in a raise load.with_traceback(rebuilt_tb) call: https://github.com/ionelmc/python-tblib#tblib-traceback-to-dict

ncoghlan avatar Oct 26 '21 08:10 ncoghlan