【问题标题】:Collection2, insert using method, exception from unique constraint not caughtCollection2,使用方法插入,未捕获来自唯一约束的异常
【发布时间】:2014-01-29 15:51:44
【问题描述】:

我创建了一个新项目:

$ mrt create sandbox
$ mrt remove autopublish
$ mrt add collection2

并使用以下代码创建一个对键具有唯一约束的简单集合

SandBoxCollection = new Meteor.Collection('sandboxcoll', {
  schema: new SimpleSchema({
    title: {
      type: String,
      min: 3,
      unique: true,
      index: true
    }
  })
});

if (Meteor.isServer) {
  Meteor.publish('sandboxpub', function() {
    return SandBoxCollection.find();
  });
}

if (Meteor.isClient) {
  Meteor.subscribe('sandboxpub');
}

Meteor.methods({
  create: function(doc) {
    var docId = SandBoxCollection.insert(doc, {validationContext: 'create'}, function(err, res) {
      if (err) {
        throw new Meteor.Error(333, SandBoxCollection.simpleSchema().namedContext('create').invalidKeys());
      }
      return res;
    });
    return docId;
  }
});

我设置了一个简单的集合、pub/sub 和一个可用于插入的方法。

然后我使用浏览器控制台发出以下命令

让我们先创建一个文档:

Meteor.call('create', {title: 'abcd01'}, function(e,r){
  console.log(e ? e : r);
});

现在让我们尝试使用 collection.insert() 直接插入一个副本:

SandBoxCollection.insert({title: 'abcd01'}, function(e,r) {
  console.log('error: ');
  console.log(e);
  console.log('errorkeys: ');
  console.log(SandBoxCollection.simpleSchema().namedContext().invalidKeys()); 
  console.log('result: ');
  console.log(r);  
});

我们可以看到由回调处理并记录到控制台的正确 333 错误。

现在尝试使用以下方法插入副本:

Meteor.call('create', {title: 'abcd01'}, function(e,r){
  console.log(e ? e : r);
});

请注意,与直接插入不同,该方法会引发未捕获的异常!此外,该错误是从我们的自定义 throw 中抛出的,错误代码为 333。

为什么没有正确处理?我可以做些什么来缓解这种情况,以便我可以对错误做一些事情(通知用户,重定向到原始文档页面等)

【问题讨论】:

    标签: meteor meteor-collection2


    【解决方案1】:

    截至 2014 年 2 月,这是对 collection2 问题跟踪器的增强请求,地址为 https://github.com/aldeed/meteor-collection2/issues/59

    当前的解决方法(在服务器上)是单独捕获错误并将其输入到自定义 Meteor.Error 中,如下所示:

    if (Meteor.isServer) {
      Meteor.methods({
        insertDocument: function(collection, document) {
          check(collection, String);
          check(document, Object);
    
          var documentId = '',
              invalidKeys = [];
    
          function doInsert() {
            documentId = SandboxProject.Collections[collection + 'Collection'].insert(document, {validationContext: collection + 'Context'});
          }
    
          try {
            doInsert();
          } catch (error) {
            invalidKeys = SandboxProject.Collections[collection + 'Collection'].simpleSchema().namedContext(collection + 'Context').invalidKeys();
            error.invalidKeys = invalidKeys;
            throw new Meteor.Error(333, error);
          }
          return documentId;
        }
      });
    }
    

    注意:这是一个通用的插入方法,它将命名空间集合名称作为参数和文档。它旨在通过回调函数从客户端调用,该回调函数将结果作为文档 ID 或错误对象返回。

    【讨论】:

    • 做和update时是否也返回了对象的ID?
    • 我不知道我没有检查。为什么需要身份证?事实上,你不是已经知道 id,因为你是通过 id 进行更新的吗?
    • 我检查了不是,只返回了受影响的文档数量,是的。我猜你已经有了 ID,因为你正在为更新指定它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 1970-01-01
    • 2018-08-14
    • 2014-09-04
    • 2017-11-17
    • 2016-12-17
    • 1970-01-01
    相关资源
    最近更新 更多