From 143e046cf523a6d342e1804d821345411fdbdf9f Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Mon, 18 Sep 2017 10:59:54 +0200 Subject: [PATCH] Attempt at passing errors to the main thread through .updates --- telethon/telegram_client.py | 7 +++++++ telethon/update_state.py | 20 +++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/telethon/telegram_client.py b/telethon/telegram_client.py index 38cf4303..bf915b04 100644 --- a/telethon/telegram_client.py +++ b/telethon/telegram_client.py @@ -230,6 +230,8 @@ class TelegramClient(TelegramBareClient): threading.get_ident() == self._recv_thread.ident: raise AssertionError('Cannot invoke requests from the ReadThread') + self.updates.check_error() + try: # Users may call this method from within some update handler. # If this is the case, then the thread invoking the request @@ -1025,5 +1027,10 @@ class TelegramClient(TelegramBareClient): self._recv_thread = None # Not running anymore self.reconnect() return + except Exception as e: + # Unknown exception, pass it to the main thread + self.updates.set_error(e) + self._recv_thread = None + return # endregion diff --git a/telethon/update_state.py b/telethon/update_state.py index f9303258..a6cf324b 100644 --- a/telethon/update_state.py +++ b/telethon/update_state.py @@ -34,7 +34,10 @@ class UpdateState: if not self._updates: self._updates_available.clear() - return update + if isinstance(update, Exception): + raise update # Some error was set through .set_error() + + return update def get_polling(self): return self._polling @@ -47,6 +50,21 @@ class UpdateState: polling = property(fget=get_polling, fset=set_polling) + def set_error(self, error): + """Sets an error, so that the next call to .poll() will raise it. + Can be (and is) used to pass exceptions between threads. + """ + with self._updates_lock: + # Insert at the beginning so the very next poll causes an error + # TODO Should this reset the pts and such? + self._updates.insert(0, error) + self._updates_available.set() + + def check_error(self): + with self._updates_lock: + if self._updates and isinstance(self._updates[0], Exception): + raise self._updates.pop() + def process(self, update): """Processes an update object. This method is normally called by the library itself.