mirror of
https://github.com/Steffo99/greed.git
synced 2024-11-24 14:54:18 +00:00
Handle correctly telegram exceptions
This commit is contained in:
parent
2ba2be62ff
commit
ffc5bbb5f6
3 changed files with 31 additions and 52 deletions
35
core.py
35
core.py
|
@ -36,39 +36,8 @@ def main():
|
||||||
# Main loop of the program
|
# Main loop of the program
|
||||||
while True:
|
while True:
|
||||||
# Get a new batch of 100 updates and mark the last 100 parsed as read
|
# Get a new batch of 100 updates and mark the last 100 parsed as read
|
||||||
try:
|
updates = bot.get_updates(offset=next_update,
|
||||||
updates = bot.get_updates(offset=next_update,
|
timeout=int(configloader.config["Telegram"]["long_polling_timeout"]))
|
||||||
timeout=int(configloader.config["Telegram"]["long_polling_timeout"]))
|
|
||||||
# If the method times out...
|
|
||||||
except telegram.error.TimedOut:
|
|
||||||
# Increase the TimedOut counter
|
|
||||||
timed_out_counter += 1
|
|
||||||
# Notify on stdout
|
|
||||||
print(f"WARNING: get_updates timed out ({timed_out_counter} time{'s' if timed_out_counter != 1 else ''})")
|
|
||||||
# Try again
|
|
||||||
continue
|
|
||||||
# If the method raises a NetworkError (connection problems)...
|
|
||||||
except telegram.error.NetworkError:
|
|
||||||
# Increase the TimedOut counter
|
|
||||||
timed_out_counter += 1
|
|
||||||
# Notify on stdout
|
|
||||||
print(f"ERROR: get_updates raised a NetworkError ({timed_out_counter} time{'s' if timed_out_counter != 1 else ''})")
|
|
||||||
# Wait some time before retrying
|
|
||||||
time.sleep(3)
|
|
||||||
continue
|
|
||||||
# If Telegram returns an error...
|
|
||||||
except telegram.error.TelegramError as e:
|
|
||||||
# Increase the TimedOut counter
|
|
||||||
timed_out_counter += 1
|
|
||||||
# Notify on stdout
|
|
||||||
print(f"ERROR: telegram returned an error while trying to get_updates ({e.message}) ({timed_out_counter} time{'s' if timed_out_counter != 1 else ''})")
|
|
||||||
# Wait some time before retrying
|
|
||||||
time.sleep(3)
|
|
||||||
continue
|
|
||||||
# If all goes well...
|
|
||||||
else:
|
|
||||||
# Reset the TimedOut counter
|
|
||||||
timed_out_counter = 0
|
|
||||||
# Parse all the updates
|
# Parse all the updates
|
||||||
for update in updates:
|
for update in updates:
|
||||||
# If the update is a message...
|
# If the update is a message...
|
||||||
|
|
36
utils.py
36
utils.py
|
@ -5,6 +5,7 @@ from configloader import config
|
||||||
from strings import currency_format_string, currency_symbol
|
from strings import currency_format_string, currency_symbol
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
|
|
||||||
class Price:
|
class Price:
|
||||||
def __init__(self, value:typing.Union[int, float, str, "Price"]=0):
|
def __init__(self, value:typing.Union[int, float, str, "Price"]=0):
|
||||||
if isinstance(value, int):
|
if isinstance(value, int):
|
||||||
|
@ -92,18 +93,23 @@ def catch_telegram_errors(func):
|
||||||
def result_func(*args, **kwargs):
|
def result_func(*args, **kwargs):
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
|
# Bot was blocked by the user
|
||||||
except telegram.error.Unauthorized:
|
except telegram.error.Unauthorized:
|
||||||
print(f"Unauthorized to call {func.__name__}(), skipping.")
|
print(f"Unauthorized to call {func.__name__}(), skipping.")
|
||||||
break
|
break
|
||||||
|
# Telegram API didn't answer in time
|
||||||
except telegram.error.TimedOut:
|
except telegram.error.TimedOut:
|
||||||
print(f"Timed out while calling {func.__name__}(), retrying in 1 sec...")
|
print(f"Timed out while calling {func.__name__}(), retrying in 1 sec...")
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
# Telegram is not reachable
|
||||||
except telegram.error.NetworkError:
|
except telegram.error.NetworkError:
|
||||||
print(f"Network error while calling {func.__name__}(), retrying in 5 secs...")
|
print(f"Network error while calling {func.__name__}(), retrying in 5 secs...")
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
else:
|
# Unknown error
|
||||||
break
|
except telegram.error.TelegramError:
|
||||||
|
print(f"Telegram error while calling {func.__name__}(), retrying in 5 secs...")
|
||||||
|
time.sleep(5)
|
||||||
return result_func
|
return result_func
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,46 +119,46 @@ class DuckBot:
|
||||||
|
|
||||||
@catch_telegram_errors
|
@catch_telegram_errors
|
||||||
def send_message(self, *args, **kwargs):
|
def send_message(self, *args, **kwargs):
|
||||||
self.bot.send_message(*args, **kwargs)
|
return self.bot.send_message(*args, **kwargs)
|
||||||
|
|
||||||
@catch_telegram_errors
|
@catch_telegram_errors
|
||||||
def edit_message_text(self, *args, **kwargs):
|
def edit_message_text(self, *args, **kwargs):
|
||||||
self.bot.edit_message_text(*args, **kwargs)
|
return self.bot.edit_message_text(*args, **kwargs)
|
||||||
|
|
||||||
@catch_telegram_errors
|
@catch_telegram_errors
|
||||||
def edit_message_caption(self, *args, **kwargs):
|
def edit_message_caption(self, *args, **kwargs):
|
||||||
self.bot.edit_message_caption(*args, **kwargs)
|
return self.bot.edit_message_caption(*args, **kwargs)
|
||||||
|
|
||||||
@catch_telegram_errors
|
@catch_telegram_errors
|
||||||
def edit_message_reply_markup(self, *args, **kwargs):
|
def edit_message_reply_markup(self, *args, **kwargs):
|
||||||
self.bot.edit_message_reply_markup(*args, **kwargs)
|
return self.bot.edit_message_reply_markup(*args, **kwargs)
|
||||||
|
|
||||||
@catch_telegram_errors
|
@catch_telegram_errors
|
||||||
def get_updates(self, *args, **kwargs):
|
def get_updates(self, *args, **kwargs):
|
||||||
self.bot.get_updates(*args, **kwargs)
|
return self.bot.get_updates(*args, **kwargs)
|
||||||
|
|
||||||
@catch_telegram_errors
|
@catch_telegram_errors
|
||||||
def get_me(self, *args, **kwargs):
|
def get_me(self, *args, **kwargs):
|
||||||
self.bot.get_me(*args, **kwargs)
|
return self.bot.get_me(*args, **kwargs)
|
||||||
|
|
||||||
@catch_telegram_errors
|
@catch_telegram_errors
|
||||||
def answer_callback_query(self, *args, **kwargs):
|
def answer_callback_query(self, *args, **kwargs):
|
||||||
self.bot.answer_callback_query(*args, **kwargs)
|
return self.bot.answer_callback_query(*args, **kwargs)
|
||||||
|
|
||||||
@catch_telegram_errors
|
@catch_telegram_errors
|
||||||
def answer_pre_checkout_query(self, *args, **kwargs):
|
def answer_pre_checkout_query(self, *args, **kwargs):
|
||||||
self.bot.answer_pre_checkout_query(*args, **kwargs)
|
return self.bot.answer_pre_checkout_query(*args, **kwargs)
|
||||||
|
|
||||||
@catch_telegram_errors
|
@catch_telegram_errors
|
||||||
def send_invoice(self, *args, **kwargs):
|
def send_invoice(self, *args, **kwargs):
|
||||||
self.bot.send_invoice(*args, **kwargs)
|
return self.bot.send_invoice(*args, **kwargs)
|
||||||
|
|
||||||
@catch_telegram_errors
|
@catch_telegram_errors
|
||||||
def get_file(self, *args, **kwargs):
|
def get_file(self, *args, **kwargs):
|
||||||
self.bot.get_file(*args, **kwargs)
|
return self.bot.get_file(*args, **kwargs)
|
||||||
|
|
||||||
@catch_telegram_errors
|
@catch_telegram_errors
|
||||||
def send_chat_action(self, *args, **kwargs):
|
def send_chat_action(self, *args, **kwargs):
|
||||||
self.bot.send_chat_action(*args, **kwargs)
|
return self.bot.send_chat_action(*args, **kwargs)
|
||||||
|
|
||||||
# TODO: add more methods
|
# TODO: add more methods
|
||||||
|
|
12
worker.py
12
worker.py
|
@ -12,6 +12,7 @@ import re
|
||||||
import utils
|
import utils
|
||||||
from html import escape
|
from html import escape
|
||||||
|
|
||||||
|
|
||||||
class StopSignal:
|
class StopSignal:
|
||||||
"""A data class that should be sent to the worker when the conversation has to be stopped abnormally."""
|
"""A data class that should be sent to the worker when the conversation has to be stopped abnormally."""
|
||||||
|
|
||||||
|
@ -45,7 +46,6 @@ class ChatWorker(threading.Thread):
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""The conversation code."""
|
"""The conversation code."""
|
||||||
# TODO: catch all the possible exceptions
|
|
||||||
# Welcome the user to the bot
|
# Welcome the user to the bot
|
||||||
self.bot.send_message(self.chat.id, strings.conversation_after_start)
|
self.bot.send_message(self.chat.id, strings.conversation_after_start)
|
||||||
# Get the user db data from the users and admin tables
|
# Get the user db data from the users and admin tables
|
||||||
|
@ -78,6 +78,7 @@ class ChatWorker(threading.Thread):
|
||||||
# Wait for the thread to stop
|
# Wait for the thread to stop
|
||||||
self.join()
|
self.join()
|
||||||
|
|
||||||
|
# noinspection PyUnboundLocalVariable
|
||||||
def __receive_next_update(self) -> telegram.Update:
|
def __receive_next_update(self) -> telegram.Update:
|
||||||
"""Get the next update from the queue.
|
"""Get the next update from the queue.
|
||||||
If no update is found, block the process until one is received.
|
If no update is found, block the process until one is received.
|
||||||
|
@ -95,7 +96,9 @@ class ChatWorker(threading.Thread):
|
||||||
# Return the received update
|
# Return the received update
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def __wait_for_specific_message(self, items:typing.List[str], cancellable:bool=False) -> typing.Union[str, CancelSignal]:
|
def __wait_for_specific_message(self,
|
||||||
|
items: typing.List[str],
|
||||||
|
cancellable: bool=False) -> typing.Union[str, CancelSignal]:
|
||||||
"""Continue getting updates until until one of the strings contained in the list is received as a message."""
|
"""Continue getting updates until until one of the strings contained in the list is received as a message."""
|
||||||
while True:
|
while True:
|
||||||
# Get the next update
|
# Get the next update
|
||||||
|
@ -116,7 +119,7 @@ class ChatWorker(threading.Thread):
|
||||||
# Return the message text
|
# Return the message text
|
||||||
return update.message.text
|
return update.message.text
|
||||||
|
|
||||||
def __wait_for_regex(self, regex:str, cancellable:bool=False) -> typing.Union[str, CancelSignal]:
|
def __wait_for_regex(self, regex: str, cancellable: bool=False) -> typing.Union[str, CancelSignal]:
|
||||||
"""Continue getting updates until the regex finds a match in a message, then return the first capture group."""
|
"""Continue getting updates until the regex finds a match in a message, then return the first capture group."""
|
||||||
while True:
|
while True:
|
||||||
# Get the next update
|
# Get the next update
|
||||||
|
@ -139,7 +142,8 @@ class ChatWorker(threading.Thread):
|
||||||
# Return the first capture group
|
# Return the first capture group
|
||||||
return match.group(1)
|
return match.group(1)
|
||||||
|
|
||||||
def __wait_for_precheckoutquery(self, cancellable:bool=False) -> typing.Union[telegram.PreCheckoutQuery, CancelSignal]:
|
def __wait_for_precheckoutquery(self,
|
||||||
|
cancellable: bool=False) -> typing.Union[telegram.PreCheckoutQuery, CancelSignal]:
|
||||||
"""Continue getting updates until a precheckoutquery is received.
|
"""Continue getting updates until a precheckoutquery is received.
|
||||||
The payload is checked by the core before forwarding the message."""
|
The payload is checked by the core before forwarding the message."""
|
||||||
while True:
|
while True:
|
||||||
|
|
Loading…
Reference in a new issue