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

#meteor #meteor-publications

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

Я что-то здесь упускаю?

Комментарии:

1. Хороший вопрос. Никогда раньше не сталкивался с необходимостью в этом. Что на самом деле происходит, когда вы не улавливаете ошибку? При вызовах методов обычно просто генерируются исключения, и они будут отправлены клиенту. Разве это не то же самое в публикациях? То есть, если вы не попытаетесь перехватить исключение, клиент получит еще менее значимую информацию?

2. К сожалению, это приводит к той же общей исправленной ошибке 500.

3. Что происходит, когда вы вручную создаете новый Meteor.Error объект вместо пересылки pubErr ? Кроме того, что вы используете, чтобы вызвать ошибку публикации? — просто чтобы другие могли воспроизвести.

4. Спасибо, воспроизведение в чистом проекте сработало, поэтому я искал проблему и нашел ее, я добавлю ее в качестве ответа здесь, на случай, если другие столкнутся с подобной проблемой.

Ответ №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