升级后lodash.clonedeep栈溢出:mongoose连接MongoSessionStore异常
升级依赖并切换Mongo会话存储后出现
lodash.clonedeep栈溢出错误 运行时抛出栈溢出错误,具体日志如下:
/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 ...
当前依赖版本
| 依赖项 | 版本 |
|---|---|
| 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 |
相关配置代码
会话存储配置
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, }) );
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 |
问题原因及解决建议
- 循环引用是核心诱因:
lodash.clonedeep遇到循环引用对象会触发无限递归,最终导致栈溢出。升级后依赖(尤其是mongoose v6+、connect-mongodb-session)返回的对象结构与旧版本不同,新增了循环引用链,而代码中使用cloneDeep的位置未做处理。 - 排查
cloneDeep调用场景:遍历代码中所有_.cloneDeep()的使用位置,检查传入的对象是否包含mongoose连接实例、会话对象或其他MongoDB相关实例。这类实例在新版本中可能存在内部循环引用(比如连接实例引用数据库,数据库又引用连接);若不需要深克隆整个对象,改用浅克隆(_.clone())或手动提取需要的属性进行克隆。 - 调整会话存储配置:新版本
connect-mongodb-session对mongoose连接的处理与旧版connect-mongo不同,尝试不使用mongooseConnection参数,改用直接传入MongoDB客户端实例:
同时检查// 从mongoose中获取客户端实例 const client = mongoose.connection.getClient(); const sessionMongoStore = new MongoStore({ autoReconnect: true, client: client });autoReconnect参数是否已被弃用,参考官方文档调整配置项。 - 验证lodash版本兼容性:临时回退到旧版lodash v4.17.13,验证是否能解决问题,帮助定位是否是lodash与新依赖的兼容性问题。
- 检查db.ts相关调用:当前db.ts导入lodash但未直接使用
cloneDeep,需确认是否有其他代码间接克隆了mongoose导出的整个实例。mongoose实例本身包含大量循环引用的内部属性,若存在_.cloneDeep(mongoose)这类调用,必然触发栈溢出,确保只克隆需要的属性而非整个mongoose对象。
内容的提问来源于stack exchange,提问作者mfeb
相关产品推荐
相关产品推荐

