Публикация Meteor отправляет клиенту пользовательскую очищенную ошибку в публикации

Я не уверен, что я просто делаю что-то не так или это на самом деле не работает. Я хочу отобразить исходную ошибку публикации на клиенте, если я ее поймал:

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
  }
})

Однако на сервере pubErr является Meteor.Error и согласно документации он должен быть отправлен клиенту, клиент просто получает общее очищенное сообщение об ошибке:

на сервере

{
  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, как указано в документации, но безуспешно.

Я что-то упустил здесь?


person Jankapunkt    schedule 13.08.2020    source источник
comment
Хороший вопрос. Раньше никогда не сталкивался с необходимостью в этом. Что на самом деле происходит, когда вы не ловите ошибку? В вызовах методов принято просто генерировать исключения, и они будут отправлены клиенту. Разве не то же самое в публикациях? То есть, если вы не попытаетесь поймать исключение, клиент получит еще менее значимую информацию?   -  person Christian Fritz    schedule 14.08.2020
comment
К сожалению, это приводит к той же общей очищенной ошибке 500.   -  person Jankapunkt    schedule 14.08.2020
comment
Что происходит, когда вы вручную создаете новый объект Meteor.Error, а не пересылаете pubErr? Кроме того, что вы используете, чтобы вызвать ошибку публикации? -- только так другие могут воспроизвести.   -  person Christian Fritz    schedule 14.08.2020
comment
Спасибо, воспроизведение на чистом проекте сработало, поэтому я искал проблему и нашел ее, я добавлю ее в качестве ответа здесь, если другие столкнутся с подобной проблемой.   -  person Jankapunkt    schedule 14.08.2020


Ответы (1)


На самом деле я нашел ответ на вопрос после того, как меня указали в правильном направлении.

Пример кода отлично работает в новом проекте, поэтому я проверил, почему не в своем проекте, и обнаружил, что я не окружил проверку аргументов с помощью SimpleSchema с помощью try/catch (к сожалению, мой вопрос был плохо разработан, поскольку он упустил этот важный факт , главным образом потому, что я абстрагировал проверку схемы от создания публикации):

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, который на самом деле имеет те же атрибуты (error , errorType, details) как Meteor.Error, см. эта часть исходного кода контекста проверки.

Поэтому, чтобы передать правильную информацию об ошибке проверки SimpleSchema клиенту, вы должны

  • оберните его в try/catch
  • добавьте к нему флаг isClientSafe
  • в качестве альтернативы преобразовать его в Meteor.Error
  • Прикрепите к нему пользовательское свойство Meteor.Error as sanitizedError
person Jankapunkt    schedule 14.08.2020