You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Aiogram的Telegram Bot:MongoDB余额功能与FSMStorage问题排查

问题:Aiogram使用FSM时出现FSMStorageWarning警告

我正在用Aiogram框架开发Telegram Bot,用MongoDB做数据库,实现用户余额查询与修改功能时遇到问题:用户发送/balance指令后,终端弹出FSMStorageWarning警告。以下是相关代码及报错信息,尝试多种方案未解决,请求协助。

余额功能代码

from aiogram import types
from db import collection
from loader import dp 
from states.balance_state import balance
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.dispatcher import FSMContext
import motor.motor_asyncio
from aiogram.contrib.fsm_storage.memory import MemoryStorage
import asyncio

storage=MemoryStorage()

@dp.message_handler(text='/balance', state = None)
async def change_balance(message: types.Message):
    await message.answer('Amount')
    await balance.amount.set()

async def check_balance(user_id: int, amount, now_balance):
    try:
        amount = int(amount)
        if now_balance + amount >= 0:
           await change_balance(user_id, amount)
           return True
        elif now_balance + amount < 0:
            return 'no money'
    except Exception:
        return False

@dp.message_handler(state=balance.amount)
async def change_balance(message: types.Message, state: FSMContext):
    user_id = message.chat.id
    answer = message.text
    await state.update_data(amount=answer)
    check_balance = await check_balance(user_id=user_id, amount=answer) 

    now_balance = collection.find_one({"_id" : user_id})["money"]
    new_balance = now_balance + answer
    collection.update_one({"_id" : user_id}, {"$set" : {"money" : new_balance}}) 

    if check_balance == 'no money':
        await message.answer('error ')
        await state.finish
    elif check_balance:
        await message.answer('Success')
        await state.finish
    else:
        await message.answer('error')
        await state.finish

数据库操作代码

collection = cluster.Mafia_users.user
async def add_user(user_id, username):
    date = datetime.now().date()
    collection.insert_one({
        "_id" : user_id,
        "name" : username,
        "date" : str(date),
        "money" : int(1),
    })

(cluster已连接,出于安全未展示连接代码)

终端报错信息

FSMStorageWarning: You haven’t set any storage yet so no states and no data will be saved.
You can connect MemoryStorage for debug purposes or non-essential data.
  await state.set_state(self.state)

解决方案

核心问题:Storage未绑定到Dispatcher

警告的直接原因是你创建了MemoryStorage实例,但没有将它传入Dispatcher的初始化参数中,导致FSM无法存储用户状态和数据。

步骤1:绑定Storage到Dispatcher

找到你的loader.py文件(你从该文件导入了dp),修改Dispatcher初始化代码,传入storage参数:

# loader.py示例代码
from aiogram import Bot, Dispatcher
from aiogram.contrib.fsm_storage.memory import MemoryStorage

API_TOKEN = '你的Bot Token'
storage = MemoryStorage()

bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot, storage=storage)  # 关键:必须在此处传入storage

修复代码中的其他逻辑错误

除了警告,你的代码还有几个功能性问题需要修正:

  1. 函数重名:两个函数都命名为change_balance,会导致函数覆盖,建议重命名第一个函数为prompt_balance_amount
  2. 参数缺失:调用check_balance时未传入now_balance参数,会触发报错
  3. 异步操作未加await:MongoDB的motor驱动方法是异步的,调用find_one和update_one时必须加await
  4. 状态结束未执行:state.finish缺少括号,应改为await state.finish()
  5. 字符串未转整数:用户输入的金额是字符串,直接和整数余额相加会报错,需先转为整数

修正后的余额功能代码示例:

from aiogram import types
from db import collection
from loader import dp 
from states.balance_state import balance
from aiogram.dispatcher import FSMContext
import asyncio

@dp.message_handler(text='/balance', state = None)
async def prompt_balance_amount(message: types.Message):
    await message.answer('请输入金额:')
    await balance.amount.set()

async def check_balance(amount: str, now_balance: int):
    try:
        amount_int = int(amount)
        if now_balance + amount_int >= 0:
            return True, amount_int
        else:
            return 'no money', amount_int
    except ValueError:
        return False, 0

@dp.message_handler(state=balance.amount)
async def process_balance_change(message: types.Message, state: FSMContext):
    user_id = message.chat.id
    answer = message.text
    
    # 获取当前用户余额
    user_data = await collection.find_one({"_id": user_id})
    if not user_data:
        await message.answer('用户不存在,请先注册')
        await state.finish()
        return
    now_balance = user_data["money"]
    
    # 校验金额
    check_result, amount_int = await check_balance(amount=answer, now_balance=now_balance)
    
    if check_result == 'no money':
        await message.answer('余额不足,无法完成操作')
        await state.finish()
    elif check_result:
        new_balance = now_balance + amount_int
        await collection.update_one({"_id": user_id}, {"$set": {"money": new_balance}})
        await message.answer(f'操作成功!当前余额:{new_balance}')
        await state.finish()
    else:
        await message.answer('请输入有效的数字金额')
        await state.finish()

验证

修改完成后重启Bot,发送/balance指令,警告会消失,余额修改功能也能正常运行。

内容的提问来源于stack exchange,提问作者TetSigma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 23:36:17