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

Sails-Mongo 2.0添加第15个集合时报Callback was already called错误

问题描述

添加第15个数据集合时,Waterline ORM启动失败,抛出Callback was already called.错误,错误详情如下:

Error: Callback was already called.
错误调用栈:

at eval (webpack://mnUvr-api/./node_modules/async/dist/async.js?:843:36)
 at eval (webpack://mnUvr-api/./node_modules/waterline/lib/waterline/utils/system/validate-datastore-connectivity.js?:31:14)
 at eval (webpack://mnUvr-api/./node_modules/machine/lib/private/help-build-machine.js?:952:35)
 at Function.handlerCbs.error (webpack://mnUvr-api/./node_modules/machine/lib/private/help-build-machine.js?:742:26)
 at parley.retry (webpack://mnUvr-api/./node_modules/machine/lib/private/help-build-machine.js?:1088:49)
 at parley (webpack://mnUvr-api/./node_modules/parley/lib/parley.js?:140:5)
 at Object.runFn [as getConnection] (webpack://mnUvr-api/./node_modules/machine/lib/private/help-build-machine.js?:461:23)
 at validateDatastoreConnectivity (webpack://mnUvr-api/./node_modules/waterline/lib/waterline/utils/system/validate-datastore-connectivity.js?:27:25)
 at eval (webpack://mnUvr-api/./node_modules/waterline/lib/waterline.js?:722:18)
 at Object.success (webpack://mnUvr-api/./node_modules/sails-mongo/lib/index.js?:356:16)
 at eval (webpack://mnUvr-api/./node_modules/machine/lib/private/help-build-machine.js?:1517:30)
 at proceedToFinalAfterExecLC (webpack://mnUvr-api/./node_modules/parley/lib/private/Deferred.js?:1155:14)
 at proceedToInterceptsAndChecks (webpack://mnUvr-api/./node_modules/parley/lib/private/Deferred.js?:913:12)
 at proceedToAfterExecSpinlocks (webpack://mnUvr-api/./node_modules/parley/lib/private/Deferred.js?:845:10)
 at eval (webpack://mnUvr-api/./node_modules/parley/lib/private/Deferred.js?:303:7)
 at eval (webpack://mnUvr-api/./node_modules/machine/lib/private/help-build-machine.js?:954:24)

已知复现条件:

  • 集合数量达到15个时稳定触发,暂未在空白项目做复现验证
  • 使用默认无定制的数据库连接配置,Sails-Mongo版本为2.0
  • 前14个集合可正常加载使用,新增第15个集合时触发错误
  • 已排除模型本身问题:移除新增模型所有属性、确认无语法错误后,错误仍然存在

相关数据库初始化代码如下:

export const connectToDatabase = (): Promise<void> => {
  if (orm) {
    return Promise.resolve();
  }

  return new Promise((resolve, reject) => {
    Waterline.start(config, (err: unknown, _orm: Waterline.Waterline) => {
      if (err) {
        console.error("Could not start up the ORM:\n", err);
        return reject(err);
      }

      orm = _orm as Waterline;

      collections = {
        Syllabus: getModel("syllabus"),
        Clazz: getModel("clazz"),
        Move: getModel("move"),
        User: getModel<UserModel>("user"),
        Family: getModel("family"),
        Video: getModel("video"),
        ClazzLevel: getModel<ClazzModel>("clazzlevel"),
        ClazzMembership: getModel("clazzmembership"),
        syllabusOwnership: getModel("syllabusownership"),
        series: getModel("series"),
        SchoolOwnership: getModel("schoolownership"),
        School: getModel("school"),
        Product: getModel("product"),
        StudentProgress: getModel("studentprogress"),
        seriesMembership: getModel("seriesMembership"),
      };

      resolve();
    });
  });
};
根因说明

该问题是Sails-Mongo 2.0.0版本的已知缺陷:启动阶段的datastore连通性校验逻辑未做回调幂等处理,当集合数量较多时,初始化阶段的连接重试逻辑会和首次连接结果逻辑同时触发,导致同一个回调被重复调用,抛出对应错误。和模型定义本身没有关系,15个集合是触发该bug的常见并发阈值。

修复方案

按优先级从高到低选择即可:

  • 升级sails-mongo到2.1.0及以上稳定版本,官方已经在新版本中修复了该校验逻辑的回调重复调用问题,是成本最低、最稳妥的修复方式
  • 若暂时无法升级依赖,可在Waterline启动配置中添加validateDatastoreConnectivity: false配置项,跳过存在缺陷的启动连通性校验逻辑。注意关闭该配置后需要自行保证数据库连接参数正确,可在ORM启动后加一条简单的数据查询操作做连通性探测
  • 若既不能升级依赖也不想关闭校验,可在MongoDB连接串中添加参数maxPoolSize=20(设置为大于等于当前集合总数的值即可),避免初始化阶段连接池资源不足触发重试逻辑,规避回调重复调用的问题

以上方案任意一种生效后,重启服务即可正常加载全部集合,不会再抛出该错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:09:26