提问人:urfx 提问时间:10/27/2023 最后编辑:urfx 更新时间:10/27/2023 访问量:41
无法捕获然后处理Express API中的Mongoose / MongoDB错误
Cannot Catch then Handle Mongoose / MongoDB error within Express API
问:
我想让前端知道是否存在验证问题,例如重复的提交 ID。我已经准备好了许多堆栈帖子,并尝试了此代码中的各种解决方案......
简而言之,没有一个 catch 方法捕获错误。就好像 mongo 或猫鼬在我的代码进入 :( 之前扔掉了它
这是我的代码
exports.createFinishedJob = async (req, res) => {
try {
console.log('createFinishedJob req.body', req.body);
const finishedjob = new FinishedJob();
if (req.body.jobSubmissionId) { finishedjob.jobSubmissionId = req.body.jobSubmissionId };
if (req.body.customerId) { finishedjob.customerId = new ObjectId(req.body.customerId) };
finishedjob.finishedjob = req.body.finishedjob;
if (req.body.other) { finishedjob.other = req.body.other };
console.log('createFinishedJob', finishedjob);
let error;
try {
await finishedjob.save()
.catch(err => console.log("HALLO err", err));
// if (res && doc) {
// return res.json(doc);
// } else {
// return doc
// }
} catch (err) {
error = err;
console.log("createFinishedJob error", error)
}
} catch (err) {
console.error("Something went wrong")
console.error(err)
}
};
这是错误:-
(node:85241) UnhandledPromiseRejectionWarning: MongoServerError: E11000 duplicate key error collection: Genaich.processingjobs index: jobSubmissionId_1 dup key: { jobSubmissionId: "1006006" }
at /Users/urfx/phos-code/genaich/node_modules/mongodb/lib/operations/insert.js:50:33
at /Users/urfx/phos-code/genaich/node_modules/mongodb/lib/operations/command.js:84:64
at processTicksAndRejections (internal/process/task_queues.js:95:5)
(node:85241) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
这是模型
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const {ObjectId} = mongoose.Schema;
const SchemaTypes = mongoose.Schema.Types;
const finishedjobSchema = new Schema(
{
customerId: {
type: ObjectId,
ref: "User",
required: false
},
jobSubmissionId:{
type: String, // if we don't get one from the customer use payment / order number
unique: true,
index: true
},
trashed: {
type: Boolean
},
finishedjob: {
type: Object
},
other: {
type: SchemaTypes.Mixed // to start the ball rolling
}
},
{ timestamps: true });
let FinishedJob = mongoose.model("FinishedJob", finishedjobSchema);
module.exports = FinishedJob;
答:
1赞
jQueeny
10/27/2023
#1
选项一是使用该方法并捕获它抛出的任何错误。这就像一个 + 多合一的方法。像这样使用:Model.create()
Model.create()
const doc = new Model();
doc.save()
exports.createFinishedJob = async (req, res) => {
try {
// If this fails for any reason it will throw to the catch block
const finishedjob = await FinishedJob.create({
jobSubmissionId: req.body.jobSubmissionId,
customerId: req.body.customerId,
finishedjob: req.body.finishedjob,
other: req.body.other
});
// This will only return if the document was created successfully
return res.status(200).json({
message: 'Job Created'
});
} catch (err) {
console.error(err);
// Check for the E11000 duplicate key error
if(err.code === 11000){
return res.status(400).json({
message: err.message
});
}else{
return res.status(500).json({
message: 'Error on server'
});
}
}
};
选项二是快速检查 with 是否已存在,并尽早返回错误消息。但是,如果没有匹配项,那么您仍然需要再次创建新文档,这意味着对数据库的两次调用,因此,如果您每分钟处理对该路由的数千个新请求,那么效率显然会降低。像这样使用:Finishedjob
jobSubmissionId
exports.createFinishedJob = async (req, res) => {
try {
const existingFinishedjob = await FinishedJob.findOne({
jobSubmissionId: req.body.jobSubmissionId
});
if (existingFinishedjob){
return res.status(400).json({
message: 'Already exists'
});
}
const finishedjob = await FinishedJob.create({
jobSubmissionId: req.body.jobSubmissionId,
customerId: req.body.customerId,
finishedjob: req.body.finishedjob,
other: req.body.other
});
return res.status(200).json({
message: 'Job Created'
});
} catch (err) {
console.error(err);
return res.status(500).json({
message: 'Error on server'
});
}
};
评论
0赞
urfx
10/27/2023
谢谢你,我今天将测试并恢复。我已经有一个 upsert 样式方法,它检查现有作业,然后使用 create 函数。只是等待咖啡开始。非常感谢您的回答。泰
1赞
urfx
10/27/2023
#2
非常感谢@jQueeny
您使用“create”的第一个建议可以满足我的需求,但我应该稍作调整,我也想返回成功的新文档。我不能把这些都放在评论中。
/**
* THANKS @jQueeny for this working solution to handling 11000 with a catch
* using create instead of save... seems I had the clue in my method name to
* start with
* @param {*} req
* @param {*} res
* @returns duplicate error if the submissionId already exists otherwise returns the new "finished" document
*/
exports.createFinishedJob = async (req, res) => {
try {
// If this fails for any reason it will throw to the catch block
const finishedjob = await FinishedJob.create({
jobSubmissionId: req.body.jobSubmissionId,
customerId: req.body.customerId,
finishedjob: req.body.finishedjob,
other: req.body.other
});
// This will only return if the document was created successfully
if (res && finishedjob) {
console.log({"success":finishedjob});
return res.status(200).json({"success":finishedjob});
} else {
return finishedjob
}
} catch (err) {
console.error(err);
// Check for the E11000 duplicate key error
if(err.code === 11000){
return res.status(400).json({
message: err.message
});
}else{
return res.status(500).json({
message: 'Error on server'
});
}
}
};
评论
E11000 duplicate key
jobSubmissionId