如何从MongoDB重复键错误中提取集合名用于Node.js错误处理函数
从MongoDB重复键错误中提取集合名
要从MongoDB的11000重复键错误中提取集合名,核心是利用错误信息里的errmsg字段,通过正则表达式匹配其中的集合标识。
实现思路
MongoDB重复键错误的errmsg字段包含固定格式的集合信息:collection: <数据库名>.<集合名>,可以用正则表达式/collection:\s+([\w.]+)/精准捕获这段内容,进而提取出集合名。
修改后的错误控制器代码
const devErrors = (res, error) => { res.status(error.statusCode).json({ status: error.statusCode, message: error.message, stackTrace: error.stack, error: error }); } const prodErrors = (res, error) => { if (error.isOperational) { res.status(error.statusCode).json({ status: error.statusCode, message: error.message }); } else { res.status(500).json({ status: 'error', message: 'Something went wrong! Please try again later.' }); } } const castErrorHandler = (err) => { const msg = `Invalid value for ${err.path} : ${err.value}`; return new CustomError(msg, 400); } const duplicateErrorHandler = (err) => { // 兼容错误消息的两种存储位置 const errorMsg = err.errmsg || err.errorResponse?.errmsg; // 正则匹配提取集合名 const collectionMatch = errorMsg?.match(/collection:\s+([\w.]+)/); const collectionName = collectionMatch ? collectionMatch[1] : '未知集合'; // 动态获取重复字段及对应值,避免硬编码字段名 const [fieldName, fieldValue] = Object.entries(err.keyValue)[0]; const msg = `集合 ${collectionName} 中已存在值为 "${fieldValue}" 的${fieldName},请更换其他值。`; return new CustomError(msg, 400); } module.exports = (error, req, res, next) => { error.statusCode = error.statusCode || 500; error.status = error.status || 'error'; console.log('ERROR - ', error); if (error.name === "CastError") error = castErrorHandler(error); if(error.code === 11000) error = duplicateErrorHandler(error); if (process.env.NODE_ENV === "development") { devErrors(res, error); } else if (process.env.NODE_ENV === "production") { prodErrors(res, error); } }
关键细节说明
- 多结构兼容:通过
err.errmsg || err.errorResponse?.errmsg同时适配错误消息直接挂载在错误对象、或嵌套在errorResponse中的情况。 - 通用化处理:用
Object.entries(err.keyValue)[0]动态获取重复字段,无需硬编码name,适配任意重复键场景。 - 容错机制:正则匹配失败时默认返回"未知集合",避免程序因匹配失败崩溃。
内容的提问来源于stack exchange,提问作者Pradeep
相关产品推荐
相关产品推荐

