New exception class for multiple errors (#965)

This commit is contained in:
s3mple 2018-08-24 19:25:58 +03:00 committed by Lonami
parent 7e1a17352d
commit f17d7e9c5e
3 changed files with 43 additions and 4 deletions

View File

@ -6,6 +6,7 @@ import time
from .telegrambaseclient import TelegramBaseClient
from .. import errors, utils
from ..tl import TLObject, TLRequest, types, functions
from ..errors import MultiError, RPCError
__log__ = logging.getLogger(__name__)
_NOT_A_REQUEST = TypeError('You can only invoke requests, not types!')
@ -13,7 +14,8 @@ _NOT_A_REQUEST = TypeError('You can only invoke requests, not types!')
class UserMethods(TelegramBaseClient):
async def __call__(self, request, ordered=False):
for r in (request if utils.is_list_like(request) else (request,)):
requests = (request if utils.is_list_like(request) else (request,))
for r in requests:
if not isinstance(r, TLRequest):
raise _NOT_A_REQUEST
await r.resolve(self, utils)
@ -38,11 +40,21 @@ class UserMethods(TelegramBaseClient):
future = self._sender.send(request, ordered=ordered)
if isinstance(future, list):
results = []
exceptions = []
for f in future:
try:
result = await f
except RPCError as e:
exceptions.append(e)
results.append(None)
continue
self.session.process_entities(result)
exceptions.append(None)
results.append(result)
request_index += 1
if exceptions:
raise MultiError(exceptions, results, requests)
else:
return results
else:
result = await future

View File

@ -8,7 +8,7 @@ from threading import Thread
from .common import (
ReadCancelledError, TypeNotFoundError, InvalidChecksumError,
BrokenAuthKeyError, SecurityError, CdnFileTamperedError
BrokenAuthKeyError, SecurityError, CdnFileTamperedError, MultiError
)
# This imports the base errors too, as they're imported there

View File

@ -1,4 +1,5 @@
"""Errors not related to the Telegram API itself"""
from ..tl import TLRequest
class ReadCancelledError(Exception):
@ -67,3 +68,29 @@ class CdnFileTamperedError(SecurityError):
super().__init__(
'The CDN file has been altered and its download cancelled.'
)
class MultiError(Exception):
"""Exception container for multiple `TLRequest`'s."""
def __new__(cls, exceptions, result, requests):
if len(result) != len(exceptions) != len(requests):
raise ValueError(
'Need result, exception and request for each error')
for e, req in zip(exceptions, requests):
if not isinstance(e, BaseException):
raise TypeError(
'Expected and exception object, not %r' % e
)
if not isinstance(req, TLRequest):
raise TypeError(
'Expected TLRequest object, not %r' % req
)
if len(exceptions) == 1:
return exceptions[0]
self = BaseException.__new__(cls)
self.exceptions = list(exceptions)
self.results = list(result)
self.requests = list(requests)
return self