From 8ce7e776c13a39c716fd22e3b9dd4a1912a9da01 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 1 Oct 2020 12:53:17 +0300 Subject: [PATCH] Add option to raise last error instead of generic ValueError (#1571) --- telethon/client/telegrambaseclient.py | 9 +++++++++ telethon/client/users.py | 8 +++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/telethon/client/telegrambaseclient.py b/telethon/client/telegrambaseclient.py index ce80211b..444a4181 100644 --- a/telethon/client/telegrambaseclient.py +++ b/telethon/client/telegrambaseclient.py @@ -160,6 +160,12 @@ class TelegramBaseClient(abc.ABC): was for 21s, it would ``raise FloodWaitError`` instead. Values larger than a day (like ``float('inf')``) will be changed to a day. + raise_last_call_error (`bool`, optional): + When API calls fail in a way that causes Telethon to retry + automatically, should the RPC error of the last attempt be raised + instead of a generic ValueError. This is mostly useful for + detecting when Telegram has internal issues. + device_model (`str`, optional): "Device model" to be sent when creating the initial connection. Defaults to 'PC (n)bit' derived from ``platform.uname().machine``, or its direct value if unknown. @@ -216,6 +222,7 @@ class TelegramBaseClient(abc.ABC): auto_reconnect: bool = True, sequential_updates: bool = False, flood_sleep_threshold: int = 60, + raise_last_call_error: bool = False, device_model: str = None, system_version: str = None, app_version: str = None, @@ -306,6 +313,8 @@ class TelegramBaseClient(abc.ABC): ) ) + self._raise_last_call_error = raise_last_call_error + self._request_retries = request_retries self._connection_retries = connection_retries self._retry_delay = retry_delay or 0 diff --git a/telethon/client/users.py b/telethon/client/users.py index 5c806f5c..345fb339 100644 --- a/telethon/client/users.py +++ b/telethon/client/users.py @@ -50,8 +50,9 @@ class UserMethods: raise errors.FloodWaitError(request=r, capture=diff) request_index = 0 + last_error = None self._last_request = time.time() - + for attempt in retry_range(self._request_retries): try: future = sender.send(request, ordered=ordered) @@ -82,12 +83,14 @@ class UserMethods: except (errors.ServerError, errors.RpcCallFailError, errors.RpcMcgetFailError, errors.InterdcCallErrorError, errors.InterdcCallRichErrorError) as e: + last_error = e self._log[__name__].warning( 'Telegram is having internal issues %s: %s', e.__class__.__name__, e) await asyncio.sleep(2) except (errors.FloodWaitError, errors.SlowModeWaitError, errors.FloodTestPhoneWaitError) as e: + last_error = e if utils.is_list_like(request): request = request[request_index] @@ -106,6 +109,7 @@ class UserMethods: raise except (errors.PhoneMigrateError, errors.NetworkMigrateError, errors.UserMigrateError) as e: + last_error = e self._log[__name__].info('Phone migrated to %d', e.new_dc) should_raise = isinstance(e, ( errors.PhoneMigrateError, errors.NetworkMigrateError @@ -114,6 +118,8 @@ class UserMethods: raise await self._switch_dc(e.new_dc) + if self._raise_last_call_error and last_error is not None: + raise last_error raise ValueError('Request was unsuccessful {} time(s)' .format(attempt))