【问题标题】:Runtime stack overflow from lodash.clonedeep, using mongoose to establish a sessionMongoStore connection从 lodash.clonedeep 运行时堆栈溢出,使用 mongoose 建立 sessionMongoStore 连接
【发布时间】:2022-09-24 01:26:04
【问题描述】:

更新:这可能是一个更深层次的问题,与导入 lodash 无关。

看来,在我继承的这段代码中,cloneDeep 被用在了几个地方,而且它可能是一个实际问题,因为在克隆的内容中存在一些循环。如果是这样,我将关闭此问题并(可能)推出其他一些问题。

nodeJS v14.20.0
typescript v4.6.4
mongodb v4.9.1
mongoose v6.6.1
connect-mongodb-session v3.1.1
lodash v4.17.21

跨多个级别升级应用程序后,表演停止者正在通过 mongoose 配置和连接到 mongo,从 connect-mongo 切换到 connect-mongodb-session。构建完成没有错误,但运行应用程序会导致:

/Users/.../node_modules/lodash.clonedeep/index.js:841 
function baseClone(value, isDeep, isFull, customizer, key, object, stack) {
                  ^
RangeError: Maximum call stack size exceeded 
   at baseClone (/Users/.../node_modules/lodash.clonedeep/index.js:841:19)
   at /Users/.../node_modules/lodash.clonedeep/index.js:897:30
...

猫鼬配置会发生这种情况:

import mongo from \'connect-mongodb-session\';
import mongoose from \'./db\'

const MongoStore = mongo(session);

...

const sessionMongoStore = new MongoStore({
      autoReconnect: true,
      mongooseConnection: mongoose.connection
    });
    app.use(
      session({
        secret: \'Pnv68aFuBy\',
        store: sessionMongoStore,
        resave: true,
        saveUninitialized: true,
      })
    );

扩展 mongoose 以提供/定义正确配置的 mongoose 连接的文件 db.ts 包含:

import assert from \'assert\';
import mongoose from \'mongoose\';
import appEnv from \'./appenv\';
import bluebird from \'bluebird\';
import * as _ from \'lodash\';

(mongoose as any).Promise = bluebird;
 
...

mongoose.connect( connectionString)
  .then( () => { /* resolves to undefined */})
  .catch(err => {
    console.log(\'MongoDB connection error: \' + err);
  });

export default mongoose;

这一切都适用于以下版本:

nodeJS v12.22.12
typescript v3.8.3
mongodb v3.3.13
mongoose v5.9.12
connect-mongo v3.1.2
lodash v4.17.13

我想知道 db.ts 文件的包含是否为 lodash 创建了某种无限递归。

    标签: typescript mongodb mongoose lodash stack-overflow


    【解决方案1】:

    通过红鲱鱼,问题不在用户代码中,而是在已安装的节点模块之一中 - 具体来说,app.use(helmet.noCache()); 的(过时)使用包含lodash.cloneDeep 的错误使用。

    一位同事建议将 lodash.cloneDeep 替换为 clone。 “......将循环属性设置为true(然后您可以在某些地方慢慢将其设置为false,直到它失败)”。由于没有一个引用失败,因此查看许多 node_moodules 是一件简单的事情。提示是 helmet.noCache() 已被弃用的警告。

    解决这个问题很简单。在应用程序代码中:

    1. 插入import noCache from 'nocache';
    2. app.use(helmet.noCache()); 替换为app.use(noCache());

    【讨论】:

      猜你喜欢
      • 2021-05-28
      • 1970-01-01
      • 1970-01-01
      • 2013-09-11
      • 2018-01-28
      • 2010-12-22
      • 2011-05-16
      • 2012-09-29
      相关资源
      最近更新 更多