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

Telegram Bot使用mysql2时TypeError属性读取错误的处理方法咨询

解决mysql2 + telegraf-mysql-session的TypeError问题(constructor读取失败)

一、问题根源定位

当getSessionKey返回undefined(比如ctx.from/ctx.chat不存在的场景),telegraf-mysql-session内部会生成无效的SQL查询,导致mysql2接收到undefined作为sql参数,触发Cannot read properties of undefined (reading 'constructor')错误。另外,AgentID/DealerID为null时参数处理不当,也会间接引发这类SQL构建异常。

二、分步解决方案

1. 修复getSessionKey返回值,避免undefined

修改telegraf-mysql-session的初始化配置,确保getSessionKey始终返回有效字符串或明确的null,杜绝undefined返回:

const session = new MySQLSession({
  // 其他数据库配置...
  getSessionKey: (ctx) => {
    if (ctx.updateType === "callback_query") {
      ctx = ctx.update.callback_query.message;
    }
    // 兜底判断,避免返回undefined
    if (!ctx?.from || !ctx?.chat) {
      return null;
    }
    // 修正原代码的笔误:会话键应区分用户和聊天ID,避免同聊天内用户会话冲突
    return `${ctx.from.id}:${ctx.chat.id}`;
  },
});

2. SQL查询前强制参数校验

所有涉及AgentID/DealerID的查询,先校验变量合法性,提前拦截无效请求:

async function queryAgentData(agentId) {
  // 校验参数是否为空
  if (agentId === null || agentId === undefined) {
    console.warn("AgentID为空,跳过本次查询");
    return null;
  }

  try {
    const [rows] = await connection.query('SELECT * FROM agents WHERE id = ?', [agentId]);
    return rows[0];
  } catch (err) {
    console.error("Agent数据查询失败:", err);
    // 可选择抛出错误或返回默认值,根据业务需求调整
    throw err;
  }
}

3. 给mysql2连接添加全局错误捕获

防止单条查询错误导致整个Bot崩溃,给mysql2连接实例绑定错误监听:

const connection = mysql.createConnection({
  // 你的数据库配置(host、user、password等)
});

// 全局捕获连接级错误
connection.on('error', (err) => {
  console.error("MySQL连接异常:", err);
  // 致命错误触发自动重连
  if (err.fatal) {
    reconnect();
  }
});

// 自定义重连逻辑
function reconnect() {
  console.log("尝试重新连接数据库...");
  connection = mysql.createConnection(connection.config);
  connection.connect((err) => {
    if (err) {
      console.error("重连失败,10秒后重试:", err);
      setTimeout(reconnect, 10000);
    } else {
      console.log("数据库重连成功");
    }
  });
}

4. 给会话中间件包裹错误处理

避免会话操作异常导致Bot冻结,在telegraf会话中间件外层添加捕获逻辑:

bot.use(async (ctx, next) => {
  try {
    await session.middleware()(ctx, next);
  } catch (err) {
    console.error("会话中间件错误:", err);
    // 给用户发送友好提示
    await ctx.reply("服务暂时出现问题,请稍后再试");
    // 继续执行后续中间件,防止Bot阻塞
    await next();
  }
});

5. 清理无效会话数据(可选)

如果数据库中存在session_key为null/空字符串的无效记录,手动清理避免重复触发错误:

DELETE FROM sessions WHERE session_key IS NULL OR session_key = '';

三、验证方案

  • 模拟AgentID/DealerID为null的场景,确认不再触发constructor读取错误。
  • 测试ctx.from/ctx.chat不存在的场景(如频道消息),检查Bot是否能正常处理,不会冻结。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:45:48