Discord.py Bot集成MongoDB(Motor驱动)关闭连接时NoneType报错排查
常见排查方向及修复方案
1. 检查异步方法的定义与调用逻辑
确保你的数据库关闭方法是异步方法(添加async关键字),且调用时await的是正确的异步对象。如果close方法未定义为异步,但你用await db.close()调用它,就会触发该错误——因为非异步函数默认返回None,await None必然抛出NoneType相关异常。
错误写法示例:
def close(self): self.client.close() # motor的close是异步方法,此处未加async也未await
正确写法示例:
async def close(self): await self.client.close() # 用await调用异步的close方法
2. 确认MongoDB客户端实例的有效性
即便调试显示对象非None,也可能存在客户端实例的close方法本身不可被await的情况。你可以在close方法内添加打印,验证方法类型:
async def close(self): print(type(self.client)) print(type(self.client.close)) await self.client.close()
如果self.client.close的类型不是<class 'coroutine'>或异步方法类型,说明你可能误用了同步MongoDB驱动(如pymongo)。discord.py是异步框架,必须搭配异步驱动(如motor),否则同步方法无法被await,还会阻塞Bot运行。
3. 校验连接初始化流程
确保connect方法正确初始化了异步客户端并赋值。以motor为例,正确的初始化逻辑应该是:
async def connect(self): self.client = motor.motor_asyncio.AsyncIOMotorClient(MONGO_URI) # 可选:添加连接测试,验证客户端有效性 await self.client.admin.command('ping')
如果connect方法未正确赋值self.client,或赋值了同步客户端实例,后续调用close时必然出现异常。
4. 调整关闭时机
避免在Boton_ready事件触发前、或事件循环停止后调用关闭方法。建议在discord.py的on_shutdown或on_disconnect事件中执行数据库关闭操作,确保事件循环处于运行状态:
@bot.event async def on_shutdown(): await db.close()
额外提示
如果以上排查仍未解决问题,建议提供数据库操作类的完整代码(尤其是connect和close方法),以及调用这些方法的上下文代码——很多时候问题出在容易忽略的细节上,比如变量名拼写错误、客户端实例被意外覆盖为None等。
内容的提问来源于stack exchange,提问作者Reece Gibby iiGibbyz

