Skip to content

Unhandled exceptions occurring inside function passed to executor.map are swallowed #776

@naglis

Description

@naglis

Currently, if an unhandled exception occurs inside convert_doc when running dangerzone-cli, the exception is swallowed (traceback is not logged, the exit code is not changed).

This manifests in tests with dummy conversion - e.g. if shutil.copy raises an exception (e.g. src and dst being the same path), the CLIResult is still reported as a success due to the swallowed exception. Here is a demo test case.

IIUC during actual (not dummy) execution it would hide potential exceptions occurring here or here.

I believe this is because the generator returned by executor.map is not consumed - from ThreadPoolExecutor docs:

If a fn call raises an exception, then that exception will be raised when its value is retrieved from the iterator.

Here is a simplified form showing the issue:

>>> from concurrent.futures import ThreadPoolExecutor
>>>
>>> def do_work(i):
...     print(f"do_work({i})")
...     1 / 0
...
>>> with ThreadPoolExecutor(max_workers=4) as executor:
...     _ = executor.map(do_work, range(4))
...
do_work(0)
do_work(1)
do_work(2)
do_work(3)
>>>

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Done

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions