如何使用Mongoose存储JavaScript Error对象?
解决Error对象无法正确存储到MongoDB的问题
嘿,我之前也碰到过一模一样的问题!直接把原生Error对象赋值给Mongoose的Mixed字段,最后存到MongoDB里变成空对象,核心原因是Error对象的大部分属性(比如message、stack)都是不可枚举的,而Mongoose默认只会序列化对象的可枚举属性,所以才会出现这种情况。
下面给你几个实用的解决方案:
方案1:手动提取Error的关键属性存为普通对象
最直接的方式就是把Error里你需要的属性(比如message、stack、name)提取出来,存成一个普通的JavaScript对象:
// 创建Error对象 const error = new Error('Error'); // 转换成可存储的普通对象 const errorData = { name: error.name, message: error.message, stack: error.stack }; // 赋值并保存 const userLog = await UserLog.findOne({ _id: userLogID }); userLog.error = errorData; await userLog.save();
方案2:写工具函数自动转换Error为普通对象
如果需要频繁处理Error存储,可以写一个工具函数,自动提取Error的所有属性(包括不可枚举的):
function convertErrorToPlainObj(error) { if (!(error instanceof Error)) return error; return Object.getOwnPropertyNames(error).reduce((result, propName) => { result[propName] = error[propName]; return result; }, {}); } // 使用示例 const userLog = await UserLog.findOne({ _id: userLogID }); userLog.error = convertErrorToPlainObj(new Error('Error')); await userLog.save();
这个函数会遍历Error对象的所有自有属性(不管是否可枚举),把它们复制到一个普通对象里,这样Mongoose就能正常序列化存储了。
方案3:给Schema字段加Setter自动处理
更优雅的方式是在Schema定义里给error字段添加一个setter,这样每次赋值Error对象时,都会自动转换成可存储的格式:
const UserLogSchema = new Schema( { // ...你的其他字段 error: { type: Schema.Types.Mixed, set: function(value) { // 如果赋值的是Error对象,自动转换 if (value instanceof Error) { return Object.getOwnPropertyNames(value).reduce((result, prop) => { result[prop] = value[prop]; return result; }, {}); } // 如果是普通对象,直接返回 return value; } } }, { timestamps: true } ); const UserLog = mongoose.model('UserLog', UserLogSchema); // 现在你可以直接赋值Error对象了 const userLog = await UserLog.findOne({ _id: userLogID }); userLog.error = new Error('Error'); await userLog.save();
用以上任意一种方法,你都能把Error对象的关键信息正确存储到MongoDB里,而不是空对象啦!
内容的提问来源于stack exchange,提问作者THpubs
相关产品推荐
相关产品推荐

