Heroku Python应用程序(Telegram bot)每月崩溃,请求异常

sy5wg1nm  于 2023-05-23  发布在  Python
关注(0)|答案(1)|浏览(200)

我在Heroku上部署了两个使用PyTelegramBotApi(我知道不是最好的库)制作的电报机器人。一个重要的区别是:一种是使用线程来周期性地向“订阅者”(大约20人)发送通知。它大约每个月都会崩溃,Heroku控制台中的异常跟踪如下:

2022-01-14T08:00:11.068553+00:00 app[worker.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/telebot/apihelper.py", line 139, in _make_request
2022-01-14T08:00:11.068739+00:00 app[worker.1]:     result = _get_req_session().request(
2022-01-14T08:00:11.068748+00:00 app[worker.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/requests/sessions.py", line 542, in request
2022-01-14T08:00:11.068983+00:00 app[worker.1]:     resp = self.send(prep, **send_kwargs)
2022-01-14T08:00:11.068994+00:00 app[worker.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/requests/sessions.py", line 655, in send
2022-01-14T08:00:11.069233+00:00 app[worker.1]:     r = adapter.send(request, **kwargs)
2022-01-14T08:00:11.069242+00:00 app[worker.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/requests/adapters.py", line 529, in send
2022-01-14T08:00:11.069448+00:00 app[worker.1]:     raise ReadTimeout(e, request=request)
2022-01-14T08:00:11.069478+00:00 app[worker.1]: requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='api.telegram.org', port=443): Read timed out. (read timeout=25)

我没有记录以前的异常跟踪(我的错),但我记得它看起来几乎一样(最近的异常是ReadTimeout)。此外,我的任何脚本都没有出现在这个跟踪中(这让我觉得它是不完整的,由于一些Heroku日志控制台错误)。我自己不直接使用requests模块。而且它绝对不可能是由dyno睡眠引起的,因为我只使用worker dyno(它从不睡觉)。这个机器人和没有崩溃的机器人都使用Heroku Postgres。有什么想法可以导致这个异常吗?
编辑:完整的异常跟踪我不小心在调试模式下,而在我的机器上测试的东西:

Traceback (most recent call last):
  File "D:\Deadliner0307\lib\site-packages\urllib3\connectionpool.py", line 445, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "D:\Deadliner0307\lib\site-packages\urllib3\connectionpool.py", line 440, in _make_request
    httplib_response = conn.getresponse()
  File "C:\Users\vva07\AppData\Local\Programs\Python\Python39-32\lib\http\client.py", line 1347, in getresponse
    response.begin()
  File "C:\Users\vva07\AppData\Local\Programs\Python\Python39-32\lib\http\client.py", line 307, in begin
    version, status, reason = self._read_status()
  File "C:\Users\vva07\AppData\Local\Programs\Python\Python39-32\lib\http\client.py", line 268, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "C:\Users\vva07\AppData\Local\Programs\Python\Python39-32\lib\socket.py", line 704, in readinto
    return self._sock.recv_into(b)
  File "C:\Users\vva07\AppData\Local\Programs\Python\Python39-32\lib\ssl.py", line 1241, in recv_into
    return self.read(nbytes, buffer)
  File "C:\Users\vva07\AppData\Local\Programs\Python\Python39-32\lib\ssl.py", line 1099, in read
    return self._sslobj.read(len, buffer)
socket.timeout: The read operation timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "D:\Deadliner0307\lib\site-packages\requests\adapters.py", line 439, in send
    resp = conn.urlopen(
  File "D:\Deadliner0307\lib\site-packages\urllib3\connectionpool.py", line 755, in urlopen
    retries = retries.increment(
  File "D:\Deadliner0307\lib\site-packages\urllib3\util\retry.py", line 532, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "D:\Deadliner0307\lib\site-packages\urllib3\packages\six.py", line 770, in reraise
    raise value
  File "D:\Deadliner0307\lib\site-packages\urllib3\connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "D:\Deadliner0307\lib\site-packages\urllib3\connectionpool.py", line 447, in _make_request
    self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
  File "D:\Deadliner0307\lib\site-packages\urllib3\connectionpool.py", line 336, in _raise_timeout
    raise ReadTimeoutError(
urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='api.telegram.org', port=443): Read timed out. (read timeout=25)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\vva07\OneDrive\Документы\проекты\Deadliner0307\main.py", line 450, in <module>
    bot.polling(none_stop=True, interval=1)
  File "C:\Users\vva07\OneDrive\Документы\проекты\Deadliner0307\main.py", line 446, in deadliner0307
    else:
  File "D:\Deadliner0307\lib\site-packages\telebot\__init__.py", line 633, in polling
    self.__threaded_polling(non_stop, interval, timeout, long_polling_timeout, allowed_updates)
  File "D:\Deadliner0307\lib\site-packages\telebot\__init__.py", line 692, in __threaded_polling
    raise e
  File "D:\Deadliner0307\lib\site-packages\telebot\__init__.py", line 654, in __threaded_polling
    polling_thread.raise_exceptions()
  File "D:\Deadliner0307\lib\site-packages\telebot\util.py", line 100, in raise_exceptions
    raise self.exception_info
  File "D:\Deadliner0307\lib\site-packages\telebot\util.py", line 82, in run
    task(*args, **kwargs)
  File "D:\Deadliner0307\lib\site-packages\telebot\__init__.py", line 391, in __retrieve_updates
    updates = self.get_updates(offset=(self.last_update_id + 1), 
  File "D:\Deadliner0307\lib\site-packages\telebot\__init__.py", line 371, in get_updates
    json_updates = apihelper.get_updates(self.token, offset, limit, timeout, allowed_updates, long_polling_timeout)
  File "D:\Deadliner0307\lib\site-packages\telebot\apihelper.py", line 312, in get_updates
    return _make_request(token, method_url, params=payload)
  File "D:\Deadliner0307\lib\site-packages\telebot\apihelper.py", line 139, in _make_request
    result = _get_req_session().request(
  File "D:\Deadliner0307\lib\site-packages\requests\sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "D:\Deadliner0307\lib\site-packages\requests\sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "D:\Deadliner0307\lib\site-packages\requests\adapters.py", line 529, in send
    raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='api.telegram.org', port=443): Read timed out. (read timeout=25)
fcipmucu

fcipmucu1#

我已经找到了一种方法,至少可以让机器人继续工作。小心:这可能不适合您的应用程序(在您的情况下,在特定异常后直接重新启动可能会损坏数据或破坏其他东西)。在主文件中,我做了这个构造,它基本上是在一个未处理的异常之后重新启动bot,否则就会停止bot:

def exception_handler(count: int = 0):
    """Relaunching bot unless exceptions occur more than 2 times a day 
(script is reset daily on Heroku)"""
    if count < 3:
        if count > 0:
            print("An exception occurred, relaunching . . .")
            time.sleep(5)
        try:
            deadliner0307()  # bot main function with (bot.polling starts there)
        except Exception as ex:
            count += 1
            # Notifying myself about exception via free Airbrake addon:
            notifier = pybrake.Notifier(project_id=<project_id>,
                                        project_key='<project_key>',
                                        environment='production')
            notifier.notify(ex)
            exception_handler(count)
    else:
        print("Too much exceptions occurred, shutting down . . .")

if __name__ == '__main__':
    exception_handler()

相关问题