Node.js Mongoose,如何捕获后期保存中的错误

Node.js Mongoose,如何捕获后期保存中的错误,node.js,error-handling,mongoose,unique,middleware,Node.js,Error Handling,Mongoose,Unique,Middleware,我有一个集合,上面有一个唯一的字段。假设我在pre-save方法中创建此唯一字段的值,如下所示: schema.pre('save', function (next) { var _self = this; try { if (config.devMode) { log.debug('[' + si.name + ':write] - Executing presave on: ' + _self._id); }

我有一个集合,上面有一个唯一的字段。假设我在pre-save方法中创建此唯一字段的值,如下所示:

schema.pre('save', function (next) {
    var _self = this;
    try {
        if (config.devMode) {
            log.debug('[' + si.name + ':write] - Executing presave on: ' + _self._id);
        }
        if(!_self.transaction_id){
            _self.transaction_id = powm(30).toLowerCase();
        }
        next();
    } catch (e) {
        log.error('[' + si.name + ':write] - threw an error (SAVE): ', e.stack, _self);
        next(e);
    }
});
{
  value: "khsda",
  status: "FREE"
}
schema.post('save', function(err, doc, next) {
    // Handle the error...
});
Powm创建类似“dfjkfj3434jkl23k4j2k3j4asdf”的任意字符串,该字符串必须是唯一的。虽然字符串足够长,不能重复,但我希望确保如果是,我可以用一个新字符串重试保存,直到它有一个真正唯一的值为止

我知道MongoDB在保存文档时会抛出一个错误,如下所示:

documentname.save(function(err, doc){
   // If mongodb unique error then reset with a new id and resave
});

但这迫使我在代码中查找所有发生这种情况的地方。所以我想知道是否可以在post mongoose中间件中捕捉到这个错误。问题是似乎没有错误对象被传递给post save方法。那么,有什么想法吗?谢谢

我是在回答我现在发现的一个类似的问题

我将把重点放在“保存后捕获错误”部分,因为我现在不确定以这种方式修改和重新保存文档是否会引起一些麻烦。所以我不确定这是否适合您的特定需求,但您可以尝试一下

我的场景与您的类似,但略有不同:

  • 我想将一个唯一、随机、简短的代码关联到我收藏的每个文档
  • 我不会在每次插入时随机生成它,但我预先生成了一个包含1M个随机代码的集合,这些代码存储在如下文档中:

    schema.pre('save', function (next) {
        var _self = this;
        try {
            if (config.devMode) {
                log.debug('[' + si.name + ':write] - Executing presave on: ' + _self._id);
            }
            if(!_self.transaction_id){
                _self.transaction_id = powm(30).toLowerCase();
            }
            next();
        } catch (e) {
            log.error('[' + si.name + ':write] - threw an error (SAVE): ', e.stack, _self);
            next(e);
        }
    });
    
    {
      value: "khsda",
      status: "FREE"
    }
    
    schema.post('save', function(err, doc, next) {
        // Handle the error...
    });
    
  • 每次我想插入带有关联代码的新文档时,我都会执行以下操作:

  • .pre('validate',…)
    中,我选择了一个
    “FREE”
    代码,并将其状态设置为
    “PENDING”
  • 我将新文档
    代码
    分配给所选代码的
  • 现在,如果保存过程正常,我想将状态更改为
    “take”
    ,否则,我想释放代码,将其状态设置回
    “FREE”
  • 为了知道一切是否顺利,我挂接了一个
    .post('save',…)
    中间件,它将代码
    状态更改为
    “take”
  • 为了知道是否出了问题,我挂接了一个
    .post('validation',…)
    中间件。但是:我传递给中间件的函数的签名必须是
    函数(error,doc,next)
    。只有在验证过程中发生错误时,才会调用该中间件,并允许我将代码的
    状态返回到
    “FREE”
  • 因此,基本上,您可以像这样钩住一个中间件:

    schema.pre('save', function (next) {
        var _self = this;
        try {
            if (config.devMode) {
                log.debug('[' + si.name + ':write] - Executing presave on: ' + _self._id);
            }
            if(!_self.transaction_id){
                _self.transaction_id = powm(30).toLowerCase();
            }
            next();
        } catch (e) {
            log.error('[' + si.name + ':write] - threw an error (SAVE): ', e.stack, _self);
            next(e);
        }
    });
    
    {
      value: "khsda",
      status: "FREE"
    }
    
    schema.post('save', function(err, doc, next) {
        // Handle the error...
    });
    
    我不确定此时尝试更改和重新保存文档是否会导致任何问题,但从逻辑上讲,保存操作应该已经中止,在这里您可以通过
    next()
    控制错误冒泡。如果尝试新的保存,然后调用
    next()
    ,并且没有任何错误作为参数,那么它可能会根据需要工作

    让我知道这是否有效