Node.js Mongoose,如何在保存后捕获错误

R01*_*010 5 error-handling middleware unique mongoose node.js

我有一个带有独特字段的集合。假设我在 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);
    }
});
Run Code Online (Sandbox Code Playgroud)

Powm 创建了一个像 'dfjkfj3434jkl23k4j2k3j4asdf' 这样的随机字符串,它需要是唯一的。尽管字符串足够长而不会被复制,但我想确定如果是,我可以用新的字符串重试保存,直到它有一个真正独特的值。

我知道 MongoDB 在保存这样的文档时会抛出一个错误:

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

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

Onh*_*ron 1

我正在回答我现在偶然发现类似问题的情况。

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

我的情况和你的类似,但略有不同:

  1. 我想将一个独特的、随机的、短的代码与我收藏的每个文档相关联。
  2. 我不会在每次插入时随机生成它,但我预先生成了存储在文档中的 1M 随机代码的集合,如下所示:

    {
      value: "khsda",
      status: "FREE"
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 每次我想插入带有关联代码的新文档时,我都会执行以下操作:

    1. .pre('validate',...)我选择一个"FREE"代码并将其状态设置为"PENDING"
    2. 我将新文档分配codevalue所选代码的 。
    3. 现在,如果保存过程顺利,我想将状态更改为"TAKEN",否则,我想释放代码,将其状态设置回"FREE"
    4. 要知道如果一切顺利,我挂钩一个.post('save',...)中间件,将代码更改status"TAKEN"
    5. 为了知道是否出现问题,我挂接了一个.post('validation',...)中间件。但这里有一个怪癖:我传递给中间件的函数的签名必须是function(error, doc, next). 仅当验证过程中发生错误时才会调用此中间件,并让我将status代码放回"FREE".

所以,基本上,你可以像这样挂钩中间件:

schema.post('save', function(err, doc, next) {
    // Handle the error...
});
Run Code Online (Sandbox Code Playgroud)

我不确定此时尝试更改并重新保存文档是否会导致任何问题,但从逻辑上讲,保存操作应该已经中止,在这里您可以通过next(). 如果您尝试进行新的保存,然后在next()没有任何错误作为参数的情况下调用,它可能会按您的需要工作。

让我知道这个是否奏效。