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

View File

@ -8,7 +8,7 @@ from threading import Thread
from .common import ( from .common import (
ReadCancelledError, TypeNotFoundError, InvalidChecksumError, ReadCancelledError, TypeNotFoundError, InvalidChecksumError,
BrokenAuthKeyError, SecurityError, CdnFileTamperedError BrokenAuthKeyError, SecurityError, CdnFileTamperedError, MultiError
) )
# This imports the base errors too, as they're imported there # 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""" """Errors not related to the Telegram API itself"""
from ..tl import TLRequest
class ReadCancelledError(Exception): class ReadCancelledError(Exception):
@ -67,3 +68,29 @@ class CdnFileTamperedError(SecurityError):
super().__init__( super().__init__(
'The CDN file has been altered and its download cancelled.' '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