Meteor 发布向发布中的客户发送自定义清理错误

Meteor publication send custom sanitized error to client in publication

我不确定我只是做错了什么,还是这实际上不起作用。我想在客户端显示原始发布错误,以防万一:

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.Error 并且 according 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)
  }
})

所以我认为这不可能是问题的根源,但事情是这样的:Simple Schema 不是纯 Meteor 包而是 NPM 包,不会抛出 Meteor.Error 而是 Error,它实际上具有与 Meteor.Error 相同的属性(errorerrorTypedetails),请参阅验证上下文的 this part of the source code

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

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