python-telegram-bot调用run_polling时错误无法输出至控制台求助
问题解决方法
核心原因分析
- 错误处理器不触发:你直接在测试函数中抛出的
BaseException不属于python-telegram-bot框架的错误处理范畴——框架的error_handler仅捕获bot处理更新(如命令、消息、回调)过程中产生的异常,测试主线程直接抛出的错误不会被它拦截。 - 控制台卡住+错误被掩盖:
application.updater.start_polling()会启动后台异步任务,当你直接抛出错误后,测试框架终止该任务时会触发asyncio.CancelledError,相关日志会覆盖你的原始错误信息,导致控制台卡住且看不到实际错误。
具体解决方案
方案1:先优雅停止Bot,再抛出错误
在抛出测试错误前,先关闭Bot的所有后台任务,避免CancelledError干扰错误显示:
async def test(self): logging.basicConfig(level=logging.DEBUG) application = ( Application .builder() .token('MY_TELEGRAM_BOT_TOKEN') .build() ) application.add_error_handler(error_handler) await application.initialize() await application.start() await application.updater.start_polling() try: # 这里放置需要测试的逻辑或直接抛出错误 raise BaseException('my error') finally: # 必须先停止Bot任务,避免取消日志掩盖错误 await application.updater.stop() await application.stop() await application.shutdown()
方案2:测试Bot内部逻辑的错误(触发error_handler)
如果是要测试Bot命令/回调函数中的错误,需要构造模拟更新并交给Bot处理,这样error_handler才会捕获异常:
from telegram import Update, Message, Chat from telegram.ext import CommandHandler # 定义一个会抛出错误的命令处理器 async def bad_command(update, context): raise BaseException('command error') async def test(self): logging.basicConfig(level=logging.DEBUG) application = ( Application .builder() .token('MY_TELEGRAM_BOT_TOKEN') .build() ) application.add_error_handler(error_handler) application.add_handler(CommandHandler('bad', bad_command)) # 添加错误处理器 await application.initialize() await application.start() # 构造模拟更新,触发错误命令 update = Update(update_id=1, message=Message(text='/bad', chat=Chat(id=123, type='private'))) await application.process_update(update) # 处理更新,此时error_handler会触发 await application.updater.stop() await application.stop() await application.shutdown()
方案3:手动捕获并打印原始错误
如果需要强制显示测试中的错误,可以手动捕获后打印回溯,再重新抛出给unittest:
async def test(self): logging.basicConfig(level=logging.DEBUG) application = ( Application .builder() .token('MY_TELEGRAM_BOT_TOKEN') .build() ) application.add_error_handler(error_handler) await application.initialize() await application.start() await application.updater.start_polling() try: raise BaseException('my error') except BaseException as e: # 手动打印错误和回溯 print(f"实际错误内容: {e}") import traceback traceback.print_exc() raise # 重新抛出让unittest捕获 finally: await application.updater.stop() await application.stop() await application.shutdown()
内容的提问来源于stack exchange,提问作者Nathan Tew
相关产品推荐
相关产品推荐

