流星发布将自定义的已清除错误发送给发布中的客户端

问题描述

我不确定我是在做错什么还是实际上没有用。我想在客户端上显示原始发布错误,以防我发现一个错误

Meteor.publish('somePub',function (args) {
  const self = this
  try {
    // ... publication logic
  catch (pubErr) {
    self.error(pubErr)
  }
})

在客户端上,我通过onStop回调“捕获”此错误

Meteor.subscribe('somePub',args,{ 
  onStop: function (e) {
    // display e to user
  }
})

但是,在服务器上pubErrMeteor.Erroraccording to the documentation时,应该将其发送给客户端,客户端只会收到经过通用处理的错误消息:

在服务器上

{
  stack: "useful stack of actual method calls",error: "somePub.Failed",reason: "somePub.invalidArguments",details: { arg: undefined }
}

在客户端上

{
  stack: "long list of ddp-message calls",isClientSafe: true,error: 500,reason: "Internal server error",details: undefined,message: "Internal server error [500]",errorType: "Meteor.Error"
}

注意:我也尝试像提到的文档中一样,将错误作为sanitizedError字段添加到自身,但也没有成功。

在这里想念东西吗?

解决方法

实际上,在指出正确的方向后,我找到了问题的答案。

该示例代码在新项目上可以正常工作,因此我检查了为什么不在我的项目中,我发现我没有使用try / catch围绕SimpleSchema进行参数验证(不幸的是,我的问题很糟糕设计它错过了这个重要事实,主要是因为我从发布创建中抽象出了模式验证):

Meteor.publish('somePub',function (args) {
  pubSchema.validate(args) // throws on fail

  const self = this
  try {
    // ... publication logic
  catch (pubErr) {
    self.error(pubErr)
  }
})

所以我认为这可能不是问题的根源,而是这样:简单模式不是纯粹的Meteor包,而是NPM包,不会抛出Meteor.Error而是{{1 }},实际上具有与Error相同的属性(errorerrorTypedetails),请参见this part of the source code的验证上下文。

因此,为了将SimpleSchema验证错误的正确信息传递给客户端,您应该

  • 将其包装在try / catch中
  • 向其中添加Meteor.Error标志
  • 或者将其转换为isClientSafe
  • 将自定义Meteor.Error作为Meteor.Error属性附加