使用Aiogram开发Bot时遇Asyncio与Aiohttp错误求助
Aiogram Bot启动时RuntimeError问题排查与修复
问题描述
我使用Aiogram开发Telegram Bot,严格遵循官方文档配置,但出现了未遇过的错误。以下是实现代码及完整报错信息:
实现代码
def on_startup(bot: Bot) -> None: asyncio.create_task(start_schedule(bot)) async def start_schedule(botself): aioschedule.every().day.at('00:00').do(lottery.lottery_finish, botself) while True: await aioschedule.run_pending() await asyncio.sleep(1) async def main(): bot = Bot(token=BOT_TOKEN, parse_mode='html') dp = Dispatcher() dp.startup.register(on_startup) dp.include_routers(main_menu.router, order.router, report.router, phone.router, location.router, receipt_scan.router, admin_panel.router, lottery_panel.router, products_panel.router, post_panel.router, markets_panel.router, early_close_panel.router, code.router, pre_admin_panel.router, availability_panel.router) await bot.delete_webhook(drop_pending_updates=True) await dp.start_polling(bot) if __name__ == '__main__': logging.basicConfig(level=logging.INFO, stream=sys.stdout) asyncio.run(main())
报错信息
Traceback (most recent call last): File "C:\Users\DTEAA\PycharmProjects\chester_users2\bot.py", line 44, in <module> asyncio.run(main()) File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\asyncio\runners.py", line 44, in run return loop.run_until_complete(main) File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 642, in run_until_complete return future.result() File "C:\Users\DTEAA\PycharmProjects\chester_users2\bot.py", line 39, in main await dp.start_polling(bot) File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\site-packages\aiogram\dispatcher\dispatcher.py", line 526, in start_polling await self.emit_startup(bot=bots[-1], **workflow_data) File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\site-packages\aiogram\dispatcher\router.py", line 230, in emit_startup await self.startup.trigger(*args, **kwargs) File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\site-packages\aiogram\dispatcher\event\event.py", line 42, in trigger await handler.call(*args, **kwargs) File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\site-packages\aiogram\dispatcher\event\handler.py", line 48, in call return await loop.run_in_executor(None, wrapped) File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\concurrent\futures\thread.py", line 52, in run result = self.fn(*self.args, **self.kwargs) File "C:\Users\DTEAA\PycharmProjects\chester_users2\bot.py", line 18, in on_startup asyncio.create_task(start_schedule(bot)) File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\asyncio\tasks.py", line 360, in create_task loop = events.get_running_loop() RuntimeError: no running event loop ERROR:asyncio:Unclosed client session client_session: <aiohttp.client.ClientSession object at 0x00000224FFE334C0> ERROR:asyncio:Unclosed connector connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x00000224FFE133A0>, 6128.968)]'] connector: <aiohttp.connector.TCPConnector object at 0x00000224FFE33340> ERROR:asyncio:Fatal error on SSL transport protocol: <asyncio.sslproto.SSLProtocol object at 0x00000224FFE33970> transport: <_ProactorSocketTransport fd=596 read=<OverlappedFuture cancelled>> Traceback (most recent call last): File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\asyncio\sslproto.py", line 684, in _process_write_backlog self._transport.write(chunk) File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\asyncio\proactor_events.py", line 359, in write self._loop_writing(data=bytes(data)) File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\asyncio\proactor_events.py", line 395, in _loop_writing self._write_fut = self._loop._proactor.send(self._sock, data) AttributeError: 'NoneType' object has no attribute 'send' sys:1: RuntimeWarning: coroutine 'start_schedule' was never awaited Exception ignored in: <function _SSLProtocolTransport.__del__ at 0x00000224EFC60D30> Traceback (most recent call last): File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\asyncio\sslproto.py", line 321, in __del__ File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\asyncio\sslproto.py", line 316, in close File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\asyncio\sslproto.py", line 593, in _start_shutdown File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\asyncio\sslproto.py", line 598, in _write_appdata File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\asyncio\sslproto.py", line 706, in _process_write_backlog File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\asyncio\sslproto.py", line 720, in _fatal_error File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\asyncio\proactor_events.py", line 151, in _force_close File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 746, in call_soon File "C:\Users\DTEAA\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 510, in _check_closed RuntimeError: Event loop is closed Process finished with exit code 1
问题根源
核心错误是RuntimeError: no running event loop,原因:
on_startup被定义为同步函数,Aiogram会将这类同步启动处理器放到线程池中执行- 线程池中的线程没有运行asyncio事件循环,调用
asyncio.create_task时无法获取当前循环,直接触发报错 - 后续的未关闭会话、SSL传输错误等都是核心错误引发的连锁反应,事件循环提前关闭导致资源未正确释放
修复代码
将on_startup改为异步函数,确保它在事件循环上下文内执行:
# 修改为异步函数 async def on_startup(bot: Bot) -> None: asyncio.create_task(start_schedule(bot)) async def start_schedule(botself): aioschedule.every().day.at('00:00').do(lottery.lottery_finish, botself) while True: await aioschedule.run_pending() await asyncio.sleep(1) async def main(): bot = Bot(token=BOT_TOKEN, parse_mode='html') dp = Dispatcher() dp.startup.register(on_startup) dp.include_routers(main_menu.router, order.router, report.router, phone.router, location.router, receipt_scan.router, admin_panel.router, lottery_panel.router, products_panel.router, post_panel.router, markets_panel.router, early_close_panel.router, code.router, pre_admin_panel.router, availability_panel.router) await bot.delete_webhook(drop_pending_updates=True) await dp.start_polling(bot) if __name__ == '__main__': logging.basicConfig(level=logging.INFO, stream=sys.stdout) asyncio.run(main())
关键说明
- 异步的
on_startup会被Aiogram直接在事件循环中调用,此时asyncio.create_task能正常获取当前运行的事件循环 - 同步函数中禁止调用依赖事件循环的asyncio API,这是异步编程的基础规范
- 修复核心错误后,后续的资源未关闭、SSL报错等问题会自动消失
内容的提问来源于stack exchange,提问作者fk3ddx
相关产品推荐
相关产品推荐

