【问题标题】:Meteor.call raises exception even with a callback functionMeteor.call 即使使用回调函数也会引发异常
【发布时间】:2015-10-20 22:48:29
【问题描述】:

我有 Meteor 方法:

Meteor.methods({
  orderStatusUpdate: function(orderId, status, note) {
    check(orderId, String);

    var statusData = {
      status: status,
    }
    if (note) {
      statusData.statusNote = note;
    }
    check(statusData, SchemaCompiled.orderStatus);

    Collections.orders.update({_id: orderId}, {$set: statusData});
  }
});

对字段 statusNote 进行自定义验证:

custom: function(){
  if (someCondition) {
    return 'required';
  }
  return false;
}

我的问题是,即使定义了回调函数:

Meteor.call('orderStatusUpdate', orderId, orderStatus, note, function (error, result) {
  // doing something
}

异常记录到控制台:

在模拟调用 'orderStatusUpdate' 的效果时出现异常 errorClass {message: "Match error: Note is required", path: "", sanitizedError: errorClass, errorType: "Match.Error", invalidKeys: Array[1]}错误:匹配错误:需要备注

据我了解,当我调用 check(...) 时会引发异常。

我怎样才能捕捉到这个异常以正确地显示给客户?

顺便说一句,回调函数也使用 error 变量集调用。

【问题讨论】:

    标签: javascript meteor meteor-methods


    【解决方案1】:

    为什么不抓住它?

    try {
      check(statusData, SchemaCompiled.orderStatus);
    } catch (e) {
      if (Meteor.isClient) {
        alert(e);
      }
      if (Meteor.isServer) {
        throw e;
      }
    }
    

    请注意,异常是在方法的模拟版本中抛出的,即直接在客户端上。服务端异常会在回调的error中传递,但是客户端代码直接抛出。上面应该可以捕捉到这一点。

    【讨论】:

    • 在这种情况下,我如何将错误发送回 autoForm 而不是 alert(e) ?
    【解决方案2】:

    引发/记录的异常与回调或缺少回调无关。

    如果方法定义在共享文件夹中(由客户端和服务器评估),则 stub 将在客户端上运行。如果它抛出任何东西,错误通常会被捕获并记录到控制台。

    回调只与服务端运行有关。

    你有很多方法来处理这个:

    1. 定义方法 server-only(在 server 文件夹中)。

      这将使该方法仅在服务器上运行,因此客户端将收到错误。

    2. 按照@ChristianFritz 的建议,在客户端上捕获并做一些事情。
    3. 使用(当前)未记录的功能 (throwStubExceptions),如果存根抛出异常,则抛出异常并阻止调用服务器方法:

      在客户端和服务器上:

      Meteor.methods({
        thrower: function() {
          throw 'catchMe!';
        }
      });
      

      然后,在客户端:

      try{
        Meteor.apply('thrower', [], {throwStubExceptions: true}, function(err, res){
          console.log('err!', err);
        })  
      } catch(e) {
        console.log('caught', e);
      }
      

      这段代码将捕获错误并记录caught catchMe!,并且不会在服务器上调用该方法。

    【讨论】:

    • stubException 的想法看起来不错,但是在这种情况下如何告诉 autoForm 将字段标记为无效错误并显示错误?
    • 我不确定。 AutoForm 有一个method 类型的表单,它调用你指定的方法,但我没有使用它。
    • 您的解决方案 (3) 删除了异常,并且正如您所说,它不会在错误后调用服务器中的方法。但它也不会在 autoForm 中显示错误,当异常出现在表单中时。有什么线索吗?
    • 当使用1或2时,异常被捕获。我不明白这有什么问题。 AutoForm 很可能使用回调中的error 参数并忽略存根,但我没有验证这一点。您可以在客户端和服务器上定义它并抛出异常。两者之间的行为可能不同,具体取决于您可用的数据类型。您也可以不同地定义这两种方法。
    • 谢谢你,它工作完美。 (3) 解决方案。你认为它会在 Meteor 新版本中改变吗?因为它没有记录
    猜你喜欢
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    相关资源
    最近更新 更多