Skip to content

Don't call done_callback if Promise raises an exception. #2544

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion telegram/ext/utils/promise.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def run(self) -> None:

finally:
self.done.set()
if self._done_callback:
if self._exception is None and self._done_callback:
try:
self._done_callback(self.result())
except Exception as exc:
Expand Down Expand Up @@ -136,6 +136,10 @@ def add_done_callback(self, callback: Callable) -> None:
"""
Callback to be run when :class:`telegram.ext.utils.promise.Promise` becomes done.

Note:
Callback won't be called if :attr:`pooled_function`
raises an exception.

Args:
callback (:obj:`callable`): The callable that will be called when promise is done.
callback will be called by passing ``Promise.result()`` as only positional argument.
Expand Down
14 changes: 14 additions & 0 deletions tests/test_promise.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,17 @@ def done_callback(_):
)
assert caplog.records[1].message.startswith("Full traceback:")
assert promise.result() == "done!"

def test_done_cb_not_run_on_excp(self):
def callback():
raise TelegramError('Error')

def done_callback(_):
self.test_flag = True

promise = Promise(callback, [], {})
promise.add_done_callback(done_callback)
promise.run()
assert isinstance(promise.exception, TelegramError)
assert promise.done
assert self.test_flag is False