Метод проверки на сервере Meteor не отображает ошибку проверки на клиенте - PullRequest
0 голосов
/ 18 апреля 2019

У меня есть этот проверенный метод на стороне сервера import / api / Shops / server / method.js :

export const shopGeocodeAddress = new ValidatedMethod({
  name: 'shops.geocodeAddress',
  validate: new SimpleSchema({
    streetName: { type: String },
    houseNumber: { type: Number },
    city: { type: String },
    state: { type: String },
    country: { type: String },
    zip: { type: String, optional: true },
  }).validator(),
  run({ streetName, houseNumber, city, state, country, zip }) {
...
...
...
...
    return location;
  },
});

Чтобы проверить сообщение об ошибке проверки на клиенте, я отправляю houseNumber в виде строки, которая приведет к сбою метода, так как она ожидает houseNumber в качестве Number. Все идет нормально. Я получаю сообщение об ошибке проверки на консоли сервера, например:

I20190418-10:55:28.605(-3)? Exception while invoking method 'shops.geocodeAddress' { ClientError: House number must be of type Number
...
...
I20190418-10:55:28.608(-3)?   errorType: 'ClientError',
I20190418-10:55:28.608(-3)?   name: 'ClientError',
I20190418-10:55:28.608(-3)?   error: 'validation-error',
I20190418-10:55:28.609(-3)?   details: 
I20190418-10:55:28.609(-3)?    [ { name: 'houseNumber',
I20190418-10:55:28.609(-3)?        value: NaN,
I20190418-10:55:28.609(-3)?        type: 'expectedType',
I20190418-10:55:28.609(-3)?        dataType: 'Number',
I20190418-10:55:28.609(-3)?        message: 'House number debe ser del tipo Number' } ] }

Но на клиенте я получаю только внутреннюю ошибку сервера, подобную этой:

details: undefined
error: 500
errorType: "Meteor.Error"
isClientSafe: true
message: "Internal server error [500]"
reason: "Internal server error"

Таким образом, я не могу указать клиенту, какой тип ошибки или какое поле необходимо изменить, чтобы метод работал правильно.

Есть ли способ отловить ошибки проверки на методах сервера и отправить их клиенту?

Спасибо за совет!

Ответы [ 3 ]

1 голос
/ 19 апреля 2019

2 вещи: А) Вы можете написать

city: String,
state: String,
zip: { type: String, optional: true }
...

B) Вы говорите "проверенный метод на стороне сервера". Ваш метод должен находиться в общем пространстве, доступном как для сервера, так и для клиента. В методе вы заключаете все в сервер. Вы вызываете метод с клиента (и достигаете его), но запускаете его на сервере:

export const shopGeocodeAddress = new ValidatedMethod({
  name: 'shops.geocodeAddress',
  validate: new SimpleSchema({
    streetName: String,
    houseNumber: Number,
    city: String,
    state: String,
    country: String,
    zip: { type: String, optional: true },
  }).validator(),
  run({ streetName, houseNumber, city, state, country, zip }) {
     if (Meteor.isServer) {
      ...
      ...
      ...
      ...
    return location;
     }

  },
});

1 голос
/ 18 апреля 2019

Вы можете окружить schema.validator с попыткой / ловлей и выбрасыванием пользовательского Meteor.Error, который содержит более понятную информацию.

Вы можете сделать то же самое с кодом внутри run.

Если вы хотите сделать это для каждого проверенного метода, вы можете создать простую функцию генератора:

const createMethod = options => new ValidatedMethod({
  name: options.name,
  validate(...args) {
    try {
      new SimpleSchema(options.schema).validate(...args)
    } catch (e) {
      throw new Meteor.Error('validationError', e.reason)
    }
  },
  run(...args) {
    try {
      return options.run.call(this, ...args)
    } catch (e) {
      throw new Meteor.Error('methodError', e.reason)
    }    
  }
})

Обратите внимание, что вы можете использовать e.reason || e.message

0 голосов
/ 19 апреля 2019

Наконец, я использовал этот ответ на форумах Meteor https://forums.meteor.com/t/server-validated-method-doesnt-display-validation-error-on-client/48635/2?u=razor7

По сути, мне нужно было создать новый файл для запуска при запуске сервера, чтобы направлять ошибки проверки клиенту

import SimpleSchema from 'simpl-schema';

SimpleSchema.defineValidationErrorTransform((error) => {
  const ddpError = new Meteor.Error(error.message);
  ddpError.error = 'validation-error';
  ddpError.details = error.details;
  ddpError.reason = error.message;

  return ddpError;
});
...