2017-11-26 19:06:09 +03:00
|
|
|
"""
|
|
|
|
This module holds all the base and automatically generated errors that the
|
|
|
|
Telegram API has. See telethon_generator/errors.json for more.
|
|
|
|
"""
|
2017-08-25 16:34:20 +03:00
|
|
|
import urllib.request
|
2017-06-10 12:47:51 +03:00
|
|
|
import re
|
2017-09-25 12:56:44 +03:00
|
|
|
from threading import Thread
|
2017-06-10 12:47:51 +03:00
|
|
|
|
|
|
|
from .common import (
|
2017-12-28 02:22:28 +03:00
|
|
|
ReadCancelledError, TypeNotFoundError, InvalidChecksumError,
|
|
|
|
BrokenAuthKeyError, SecurityError, CdnFileTamperedError
|
2017-06-10 12:47:51 +03:00
|
|
|
)
|
|
|
|
|
2017-10-20 16:44:43 +03:00
|
|
|
# This imports the base errors too, as they're imported there
|
2018-04-14 18:22:39 +03:00
|
|
|
from .rpc_base_errors import *
|
2017-10-20 16:44:43 +03:00
|
|
|
from .rpc_error_list import *
|
2017-06-10 12:47:51 +03:00
|
|
|
|
|
|
|
|
2017-09-25 12:56:44 +03:00
|
|
|
def report_error(code, message, report_method):
|
2017-11-26 19:06:09 +03:00
|
|
|
"""
|
|
|
|
Reports an RPC error to pwrtelegram.
|
|
|
|
|
|
|
|
:param code: the integer code of the error (like 400).
|
|
|
|
:param message: the message representing the error.
|
|
|
|
:param report_method: the constructor ID of the function that caused it.
|
|
|
|
"""
|
2017-09-25 12:56:44 +03:00
|
|
|
try:
|
|
|
|
# Ensure it's signed
|
|
|
|
report_method = int.from_bytes(
|
|
|
|
report_method.to_bytes(4, 'big'), 'big', signed=True
|
|
|
|
)
|
|
|
|
url = urllib.request.urlopen(
|
|
|
|
'https://rpc.pwrtelegram.xyz?code={}&error={}&method={}'
|
2017-09-25 13:00:09 +03:00
|
|
|
.format(code, message, report_method),
|
|
|
|
timeout=5
|
2017-09-25 12:56:44 +03:00
|
|
|
)
|
|
|
|
url.read()
|
|
|
|
url.close()
|
|
|
|
except:
|
|
|
|
"We really don't want to crash when just reporting an error"
|
|
|
|
|
|
|
|
|
2018-06-09 14:11:49 +03:00
|
|
|
def rpc_message_to_error(rpc_error, report_method=None):
|
2017-11-26 19:06:09 +03:00
|
|
|
"""
|
|
|
|
Converts a Telegram's RPC Error to a Python error.
|
|
|
|
|
2018-06-09 14:11:49 +03:00
|
|
|
:param rpc_error: the RpcError instance.
|
2017-11-26 19:06:09 +03:00
|
|
|
:param report_method: if present, the ID of the method that caused it.
|
|
|
|
:return: the RPCError as a Python exception that represents this error.
|
|
|
|
"""
|
2017-08-25 16:34:20 +03:00
|
|
|
if report_method is not None:
|
2017-09-25 12:56:44 +03:00
|
|
|
Thread(
|
2017-09-25 12:57:42 +03:00
|
|
|
target=report_error,
|
2018-06-09 14:11:49 +03:00
|
|
|
args=(rpc_error.error_code, rpc_error.error_message, report_method)
|
2017-09-25 12:56:44 +03:00
|
|
|
).start()
|
2017-08-25 16:34:20 +03:00
|
|
|
|
2017-10-20 16:44:43 +03:00
|
|
|
# Try to get the error by direct look-up, otherwise regex
|
|
|
|
# TODO Maybe regexes could live in a separate dictionary?
|
2018-06-09 14:11:49 +03:00
|
|
|
cls = rpc_errors_all.get(rpc_error.error_message, None)
|
2017-10-20 16:44:43 +03:00
|
|
|
if cls:
|
|
|
|
return cls()
|
|
|
|
|
|
|
|
for msg_regex, cls in rpc_errors_all.items():
|
2018-06-09 14:11:49 +03:00
|
|
|
m = re.match(msg_regex, rpc_error.error_message)
|
2017-10-20 16:44:43 +03:00
|
|
|
if m:
|
|
|
|
capture = int(m.group(1)) if m.groups() else None
|
|
|
|
return cls(capture=capture)
|
|
|
|
|
2018-06-09 14:11:49 +03:00
|
|
|
if rpc_error.error_code == 400:
|
|
|
|
return BadRequestError(rpc_error.error_message)
|
2017-06-10 12:47:51 +03:00
|
|
|
|
2018-06-09 14:11:49 +03:00
|
|
|
if rpc_error.error_code == 401:
|
|
|
|
return UnauthorizedError(rpc_error.error_message)
|
2017-06-10 12:47:51 +03:00
|
|
|
|
2018-06-09 14:11:49 +03:00
|
|
|
if rpc_error.error_code == 403:
|
|
|
|
return ForbiddenError(rpc_error.error_message)
|
2017-06-10 12:47:51 +03:00
|
|
|
|
2018-06-09 14:11:49 +03:00
|
|
|
if rpc_error.error_code == 404:
|
|
|
|
return NotFoundError(rpc_error.error_message)
|
2017-06-10 12:47:51 +03:00
|
|
|
|
2018-06-09 14:11:49 +03:00
|
|
|
if rpc_error.error_code == 406:
|
|
|
|
return AuthKeyError(rpc_error.error_message)
|
2018-03-30 13:18:18 +03:00
|
|
|
|
2018-06-09 14:11:49 +03:00
|
|
|
if rpc_error.error_code == 500:
|
|
|
|
return ServerError(rpc_error.error_message)
|
2017-06-10 12:47:51 +03:00
|
|
|
|
2018-06-09 14:11:49 +03:00
|
|
|
return RPCError('{} (code {})'.format(
|
|
|
|
rpc_error.error_message, rpc_error.error_code))
|