如何在请求中优雅地处理连接错误?

2024-05-06 04:13:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个简单的python telegram机器人,代码如下:

import requests
import json
from time import sleep
import os

filename = 'bot_last_update'
target = open(filename, 'r')
update_from_file = target.read()

# check update from file
update_from_file = update_from_file.strip()
last_update = int(update_from_file)

token = xxxx
url = 'https://api.telegram.org/bot%s/' % token

# We want to keep checking for updates. So this must be a never ending loop
while True:
    # My chat is up and running, I need to maintain it! Get me all chat updates
    get_updates = json.loads(requests.get(url + 'getUpdates').content)
    # Ok, I've got 'em. Let's iterate through each one
    for update in get_updates['result']:
        # First make sure I haven't read this update yet
        if last_update < update['update_id']:
            last_update = update['update_id']
            target = open(filename, 'w')
            target.truncate()
            target.write(str(last_update))
            target.close()
            if update['message']['chat']['type'] == 'private':
            # I've got a new update. Let's see what it is.
                if update['message']['text'] == 'do something':
                    requests.get(url + 'sendMessage', params=dict(chat_id=update['message']['chat']['id'], text='doing it'))
                    os.system('/srv/scripts/do_something.sh')
                    sleep(10)
                    requests.get(url + 'sendMessage', params=dict(chat_id=update['message']['chat']['id'], text='done!'))
                else:
                    pass
    # Let's wait a few seconds for new updates
    sleep(1)

它工作正常,但每当我的网络出现问题时,就会出现以下错误:

Traceback (most recent call last):
  File "my_telegram_bot.py", line 21, in <module>
    get_updates = json.loads(requests.get(url + 'getUpdates').content)
  File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 70, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 56, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 475, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 596, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 473, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', error(113, 'No route to host'))

避免这种错误的最佳方法是什么?我想让这个机器人在任何时候都能正常工作,所以它不应该在这些事件中以关键的方式失败(或者如果失败了,它应该自动恢复/重新启动)。


Tags: infrompyidurltargetgetrequest
1条回答
网友
1楼 · 发布于 2024-05-06 04:13:29

你需要实现一个重试机制。下面是pythonHow to retry after exception in python?中的一个示例。如果连接在合理的时间内自行更正,则重试机制将使bot保持运行并避免错误。

查看Python requests exception handling以获取捕获特定异常的示例。

结合这两个例子,我们得到:

from requests import ConnectionError
import requests
import json
import time
import os
connection_timeout = 30 # seconds

。。。

# My chat is up and running, I need to maintain it! Get me all chat updates
start_time = time.time()
while True:
    try:
        get_updates = json.loads(requests.get(url + 'getUpdates').content)
        break
    except ConnectionError:
        if time.time() > start_time + connection_timeout:
            raise Exception('Unable to get updates after {} seconds of ConnectionErrors'.format(connection_timeout))
        else:
            time.sleep(1) # attempting once every second
# Ok, I've got 'em. Let's iterate through each one

。。。

这将每秒重试调用getUpdates,持续30秒,直到连接权限本身。您可以将连接超时调整为所需的大小,以覆盖间歇性连接。

相关问题 更多 >