我在猫鼬中有以下架构:
const mongoose = require('mongoose');
const uniqueValidator = require('mongoose-unique-validator');
const produtoSchema = new mongoose.Schema({
lista: { type: mongoose.Schema.Types.ObjectId, ref: 'Lista', required: true },
codexterno : { type: String, required: true },
nrogondola : { type: String, required: true },
codacessoproduto : { type: String, required: true },
desccompleta : { type: String, index: true, required: true },
nonsense : { type: String, index: true, required: true },
datetime : { type: String, index: true, required: true }
}, { timestamps: true });
produtoSchema.index({ lista: 1, codacessoproduto: 1 }, { unique: true });
produtoSchema.plugin(uniqueValidator, { message: 'Ja existe um registro cadastrado com o(a) {PATH} {VALUE}.' });
module.exports = mongoose.model('Produto', produtoSchema);
如您所见,有一个复合唯一索引(lista、codacessoproduto)以避免在同一列表中插入重复的产品代码。到现在为止还挺好。问题是这些产品插入来自使用 Readline 模块读取的文件。所有插入(列表和产品)都在 try catch 块内,但是当违反上述复合唯一索引时,try catch 块不会处理错误,而是抛出 UnhandledPromiseRejectionWarning:
(node:7656) UnhandledPromiseRejectionWarning: MongoError: E11000 重复键错误集合: Homologacao_1.produtos 索引: lista_1_codacessoproduto_1 dup key: { lista: ObjectId('6027d7606115dc1de8500",coede7006",coecess
(node:7656) UnhandledPromiseRejectionWarning:未处理的承诺拒绝。这个错误要么是因为在没有 catch 块的情况下抛出了异步函数,要么是因为拒绝了一个没有用 .catch() 处理过的承诺。要在未处理的承诺拒绝时终止节点进程,请使用 CLI 标志 --unhandled-rejections=strict
(请参阅 https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode)。 (拒绝编号:1)
这是我的代码:
try{
const { originalname, mimetype, size, buffer } = req.file;
const listaInserida = await Lista.create({
descricao: req.body.descricao,
loja: req.body.loja,
concorrente: req.body.concorrente,
file: {
originalname: originalname,
contentType: mimetype,
size: size,
data: buffer
},
status: req.body.status
});
const readInterface = await readline.createInterface({
input: Readable.from(buffer.toString()),
output: process.stdout,
console: false
});
await readInterface.on('line', function(line) {
Produto.create({
lista: listaInserida._id,
codexterno: line.substr(0, 3),
nrogondola: line.substr(3, 4),
codacessoproduto : line.substr(7, 13),
desccompleta : line.substr(20, 35),
nonsense : line.substr(55, 10),
datetime : line.substr(65)
});
});
req.flash('success', 'Registro incluído com sucesso.');
res.redirect(303, '/listas-para-cotacao');
}
catch (error) {
return next(error);
}
我最接近预期结果的是使用嵌套的 try 捕获,但这并没有停止脚本执行并按预期显示 500 错误页面。
await readInterface.on('line', async function(line) {
try{
await Produto.create({
lista: listaInserida._id,
codexterno: line.substr(0, 3),
nrogondola: line.substr(3, 4),
codacessoproduto : line.substr(7, 13),
desccompleta : line.substr(20, 35),
nonsense : line.substr(55, 10),
datetime : line.substr(65)
});
}
catch(err){
return next(err);
}
});