2017-06-10 12:47:51 +03:00
|
|
|
"""Errors not related to the Telegram API itself"""
|
2018-10-12 20:47:40 +03:00
|
|
|
import struct
|
|
|
|
|
2018-08-24 19:25:58 +03:00
|
|
|
from ..tl import TLRequest
|
2017-06-10 12:47:51 +03:00
|
|
|
|
|
|
|
|
|
|
|
class ReadCancelledError(Exception):
|
2017-11-26 19:06:09 +03:00
|
|
|
"""Occurs when a read operation was cancelled."""
|
2017-06-10 12:47:51 +03:00
|
|
|
def __init__(self):
|
2018-02-14 10:09:22 +03:00
|
|
|
super().__init__('The read operation was cancelled.')
|
2017-06-10 12:47:51 +03:00
|
|
|
|
|
|
|
|
|
|
|
class TypeNotFoundError(Exception):
|
2017-11-26 19:06:09 +03:00
|
|
|
"""
|
|
|
|
Occurs when a type is not found, for example,
|
|
|
|
when trying to read a TLObject with an invalid constructor code.
|
|
|
|
"""
|
2018-06-09 14:48:27 +03:00
|
|
|
def __init__(self, invalid_constructor_id, remaining):
|
2017-06-10 12:47:51 +03:00
|
|
|
super().__init__(
|
2018-02-14 10:09:22 +03:00
|
|
|
'Could not find a matching Constructor ID for the TLObject '
|
2018-06-09 14:48:27 +03:00
|
|
|
'that was supposed to be read with ID {:08x}. Most likely, '
|
|
|
|
'a TLObject was trying to be read when it should not be read. '
|
|
|
|
'Remaining bytes: {!r}'.format(invalid_constructor_id, remaining))
|
2017-06-10 12:47:51 +03:00
|
|
|
|
|
|
|
self.invalid_constructor_id = invalid_constructor_id
|
2018-06-09 14:48:27 +03:00
|
|
|
self.remaining = remaining
|
2017-06-10 12:47:51 +03:00
|
|
|
|
|
|
|
|
|
|
|
class InvalidChecksumError(Exception):
|
2017-11-26 19:06:09 +03:00
|
|
|
"""
|
|
|
|
Occurs when using the TCP full mode and the checksum of a received
|
|
|
|
packet doesn't match the expected checksum.
|
|
|
|
"""
|
2017-06-10 12:47:51 +03:00
|
|
|
def __init__(self, checksum, valid_checksum):
|
|
|
|
super().__init__(
|
2017-09-04 18:10:04 +03:00
|
|
|
'Invalid checksum ({} when {} was expected). '
|
|
|
|
'This packet should be skipped.'
|
2017-06-10 12:47:51 +03:00
|
|
|
.format(checksum, valid_checksum))
|
|
|
|
|
|
|
|
self.checksum = checksum
|
|
|
|
self.valid_checksum = valid_checksum
|
2017-08-28 15:17:31 +03:00
|
|
|
|
|
|
|
|
2018-10-12 20:47:40 +03:00
|
|
|
class InvalidBufferError(BufferError):
|
2017-11-26 19:06:09 +03:00
|
|
|
"""
|
2018-10-12 20:47:40 +03:00
|
|
|
Occurs when the buffer is invalid, and may contain an HTTP error code.
|
|
|
|
For instance, 404 means "forgotten/broken authorization key", while
|
2017-11-26 19:06:09 +03:00
|
|
|
"""
|
2018-10-12 20:47:40 +03:00
|
|
|
def __init__(self, payload):
|
|
|
|
self.payload = payload
|
|
|
|
if len(payload) == 4:
|
|
|
|
self.code = -struct.unpack('<i', payload)[0]
|
|
|
|
super().__init__(
|
|
|
|
'Invalid response buffer (HTTP code {})'.format(self.code))
|
|
|
|
else:
|
|
|
|
self.code = None
|
|
|
|
super().__init__(
|
|
|
|
'Invalid response buffer (too short {})'.format(self.payload))
|
2017-09-17 19:38:03 +03:00
|
|
|
|
|
|
|
|
2017-09-17 20:14:36 +03:00
|
|
|
class SecurityError(Exception):
|
2017-11-26 19:06:09 +03:00
|
|
|
"""
|
|
|
|
Generic security error, mostly used when generating a new AuthKey.
|
|
|
|
"""
|
2017-09-17 20:14:36 +03:00
|
|
|
def __init__(self, *args):
|
|
|
|
if not args:
|
|
|
|
args = ['A security check failed.']
|
2018-02-14 10:09:22 +03:00
|
|
|
super().__init__(*args)
|
2017-09-17 20:14:36 +03:00
|
|
|
|
|
|
|
|
|
|
|
class CdnFileTamperedError(SecurityError):
|
2017-11-26 19:06:09 +03:00
|
|
|
"""
|
|
|
|
Occurs when there's a hash mismatch between the decrypted CDN file
|
|
|
|
and its expected hash.
|
|
|
|
"""
|
2017-08-28 15:17:31 +03:00
|
|
|
def __init__(self):
|
|
|
|
super().__init__(
|
|
|
|
'The CDN file has been altered and its download cancelled.'
|
|
|
|
)
|
2018-08-24 19:25:58 +03:00
|
|
|
|
|
|
|
|
2018-10-12 23:17:07 +03:00
|
|
|
class AlreadyInConversationError(Exception):
|
|
|
|
"""
|
|
|
|
Occurs when another exclusive conversation is opened in the same chat.
|
|
|
|
"""
|
|
|
|
def __init__(self):
|
|
|
|
super().__init__(
|
|
|
|
'Cannot open exclusive conversation in a '
|
|
|
|
'chat that already has one open conversation'
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2018-08-24 19:25:58 +03:00
|
|
|
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):
|
2018-08-24 20:50:55 +03:00
|
|
|
if not isinstance(e, BaseException) and e is not None:
|
2018-08-24 19:25:58 +03:00
|
|
|
raise TypeError(
|
2018-08-24 20:50:55 +03:00
|
|
|
"Expected an exception object, not '%r'" % e
|
2018-08-24 19:25:58 +03:00
|
|
|
)
|
|
|
|
if not isinstance(req, TLRequest):
|
|
|
|
raise TypeError(
|
2018-08-24 20:50:55 +03:00
|
|
|
"Expected TLRequest object, not '%r'" % req
|
2018-08-24 19:25:58 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
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
|