#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
assanitizedError