Python Telegram Bot(v20)突然静默及NetworkError错误处理求助
处理python-telegram-bot v20中的NetworkError(httpx.ConnectError)
我用python-telegram-bot v20开发的Telegram机器人偶尔会停止响应,并触发以下错误:
The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/Users/leakyspoon/Documents/TelegramBots/venv/lib/python3.11/site-packages/telegram/ext/_application.py", line 1729, in process_error await callback(update, context) File "/Users/leakyspoon/Documents/TelegramBots/GPT.py", line 301, in error_handler await context.bot.send_message(chat_id=492065050, text=message) File "/Users/leakyspoon/Documents/TelegramBots/venv/lib/python3.11/site-packages/telegram/ext/_extbot.py", line 2644, in send_message return await super().send_message( ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/leakyspoon/Documents/TelegramBots/venv/lib/python3.11/site-packages/telegram/_bot.py", line 388, in decorator result = await func(self, *args, **kwargs) # skipcq: PYL-E1102 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/leakyspoon/Documents/TelegramBots/venv/lib/python3.11/site-packages/telegram/_bot.py", line 814, in send_message return await self._send_message( ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/leakyspoon/Documents/TelegramBots/venv/lib/python3.11/site-packages/telegram/ext/_extbot.py", line 514, in _send_message result = await super()._send_message( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/leakyspoon/Documents/TelegramBots/venv/lib/python3.11/site-packages/telegram/_bot.py", line 566, in _send_message return await self._post( ^^^^^^^^^^^^^^^^^ File "/Users/leakyspoon/Documents/TelegramBots/venv/lib/python3.11/site-packages/telegram/_bot.py", line 476, in _post return await self._do_post( ^^^^^^^^^^^^^^^^^^^^ File "/Users/leakyspoon/Documents/TelegramBots/venv/lib/python3.11/site-packages/telegram/ext/_extbot.py", line 332, in _do_post return await super()._do_post( ^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/leakyspoon/Documents/TelegramBots/venv/lib/python3.11/site-packages/telegram/_bot.py", line 504, in _do_post return await request.post( ^^^^^^^^^^^^^^^^^^^ File "/Users/leakyspoon/Documents/TelegramBots/venv/lib/python3.11/site-packages/telegram/request/_baserequest.py", line 168, in post result = await self._request_wrapper( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/leakyspoon/Documents/TelegramBots/venv/lib/python3.11/site-packages/telegram/request/_baserequest.py", line 288, in _request_wrapper raise exc File "/Users/leakyspoon/Documents/TelegramBots/venv/lib/python3.11/site-packages/telegram/request/_baserequest.py", line 278, in _request_wrapper code, payload = await self.do_request( ^^^^^^^^^^^^^^^^^^^^^^ File "/Users/leakyspoon/Documents/TelegramBots/venv/lib/python3.11/site-packages/telegram/request/_httpxrequest.py", line 240, in do_request raise NetworkError(f"httpx.{err.__class__.__name__}: {err}") from err telegram.error.NetworkError: httpx.ConnectError: [Errno 8] nodename nor servname provided, or not known
请问如何预防该错误,或通过错误处理器进行有效处理?
预防措施
- 检查网络稳定性:这个错误本质是DNS解析失败或网络连接中断,先确保机器人运行环境的网络稳定,能正常解析Telegram的API域名(
api.telegram.org)。可以定期用ping api.telegram.org或nslookup api.telegram.org验证。 - 配置HTTPX的重试机制:python-telegram-bot v20默认用HTTPX作为请求库,你可以自定义请求对象,添加重试策略来处理临时网络故障:
from telegram.request import HTTPXRequest from httpx import Timeout, AsyncClient from httpx_sse import AsyncClient as SSEAsyncClient # 配置重试策略,针对连接错误、超时等重试3次 client = AsyncClient( timeout=Timeout(10.0, connect=5.0), limits=None, transport=None, retries=3 ) sse_client = SSEAsyncClient( timeout=Timeout(10.0, connect=5.0), limits=None, transport=None, retries=3 ) request = HTTPXRequest(client=client, sse_client=sse_client) # 在创建Application时传入自定义request application = Application.builder().token("YOUR_TOKEN").request(request).build() - 使用代理(如果需要):如果所在环境无法直接访问Telegram API,配置HTTP代理或SOCKS代理,确保代理服务器能正常解析域名。
错误处理器优化
你的现有错误处理器在触发NetworkError时还尝试发送消息,这会导致二次错误(因为此时网络已经有问题),需要修改错误处理器:
- 避免在网络错误时发送消息:先判断错误类型,如果是
NetworkError,优先记录日志,不要尝试调用Telegram API:from telegram.error import NetworkError import logging logger = logging.getLogger(__name__) async def error_handler(update, context): # 记录错误日志 logger.error(f"Update {update} caused error {context.error}") # 只在非网络错误时尝试发送通知 if not isinstance(context.error, NetworkError): try: await context.bot.send_message(chat_id=492065050, text=f"错误发生:{str(context.error)}") except Exception as e: logger.error(f"发送错误通知失败:{e}") else: logger.warning("网络连接错误,跳过通知发送") - 添加机器人自动恢复逻辑:如果检测到连续多次NetworkError,可以考虑重启机器人的更新轮询(对于Polling模式),或者重新建立Webhook连接(对于Webhook模式):
# 示例:Polling模式下的重启逻辑 async def error_handler(update, context): logger.error(f"错误:{context.error}") if isinstance(context.error, NetworkError): logger.warning("网络异常,尝试重启轮询") # 停止当前轮询 await context.application.stop() # 重新启动轮询 await context.application.run_polling()
内容的提问来源于stack exchange,提问作者LeakySpoon
相关产品推荐
相关产品推荐

