0

在服务器代码中,我无法在客户端的Meteor.call错误回调中得到错误,内部发生错误Meteor.bindEnvironment。下面是要复制的示例代码

在服务器

Meteor.methods({
  customMethod: function(arg1, arg2){
      Stripe.customers.create({
        email: "email@here.com,
        description: "blah blah",
        source: token,
        metadata: {
          planId: planId,
          quantity: n
        },
        plan: planId,
        quantity: n
      }, Meteor.bindEnvironment(function (err, customer) {
        if(err){
          console.log("error", err);
          // TODO cannot catch this error on the client
          throw new Meteor.Error(err.rawType, err.message)
        }
      }))
    }
})

在 Meteor 事件中的客户端中,

Meteor.call('customMethod', arg1, arg2, function (err, resp) {
 if(err){
   Session.set('some-error', err)
 }
 if(resp){
   // TODO cannot catch errors throwing from the server
   // when inside Meteor.bindEnvironment 
   Session.set('some-success', true)
 }
});

会话变量永远不会设置。任何帮助都会很棒。谢谢!

4

1 回答 1

0

的第二个参数Meteor.bindEnvironment是一个错误处理程序,只要在您作为第一个参数提供的回调中引发异常,就会调用该处理程序。因此,您可以执行以下操作将错误传递回客户端:

Meteor.bindEnvironment(function (err, customer) {
  if (err) throw err
  ...
}, function (err) {
  if (err) throw new Meteor.Error(err.message)
})

更新

抱歉,有点仓促。问题是您的错误(以及潜在的结果)来自异步回调,因此您的方法函数将完成执行,并在回调执行任何操作时隐式返回undefined(作为 传递给客户端null)。

从历史上看,你会用future解决这个问题,但现在我们有了更好的承诺:

Meteor.methods({
  customMethod (arg1, arg2) {
    return new Promise((resolve, reject) => {
      Stripe.customers.create({
        email: "email@here.com,
        ...
      }, Meteor.bindEnvironment(function (err, customer) {
        if(err){
          reject(err)
        }
        resolve(customer)
      })).catch(e => { throw new Meteor.Error(e) })
  }
})

Meteor 方法足够聪明,可以等待 Promise 解决或拒绝并通过 DDP 返回结果(或错误)。您仍然需要捕获错误并正式抛出它,但您的方法调用将等待您这样做。

于 2015-11-20T16:01:43.600 回答