NodeJS + Validate.js несколько асинхронных валидаторов - PullRequest
0 голосов
/ 01 ноября 2018

Я новичок в NodeJS и пытаюсь использовать собственные асинхронные валидаторы для двух полей. Причина, по которой я использую асинхронный валидатор, заключается в том, что в базу данных необходимо сделать запрос, чтобы проверить, существует ли запись с таким идентификатором. Я реализовал два валидатора (код приведен ниже) - если я использую только один из них в ограничениях validate.async, каждый из них работает. Однако, если я использую оба из них одновременно, генерируется необработанное отклонение обещания (точная ошибка также ниже), и возвращается только первая ошибка валидатора.

Код: timezoneValidateAsync:

function valAsync(value) {
    return new validate.Promise(async function(resolve, reject) {
      const timezone = await Timezone.findById(value);
      if (!timezone) {
        reject(ValidationErrors.NOSUCHTIMEZONE);
      }
      resolve();
    });
  }

  validate.validators.timezoneValidateAsync = valAsync;

languageValidateAsync:

function valAsync(value) {
    return new validate.Promise(async function(resolve, reject) {
      const language = await Language.findById(value);
      if (!language) {
        reject(ValidationErrors.NOSUCHLANGUAGE);
      }

      resolve();
    });
  }

  validate.validators.languageValidateAsync = valAsync;

Использование в validate.async:

constraints = {
      timezoneId: {
        presence: {
          message: ValidationErrors.TIMEZONEIDEXISTS
        },
        numericality: {
          greaterThan: 0,
          message: ValidationErrors.TIMEZONEIDGREATERTHANZERO
        },
        timezoneValidateAsync: {}
      },
      languageId: {
        presence: {
          message: ValidationErrors.LANGUAGEIDEXISTS
        },
        numericality: {
          greaterThan: 0,
          message: ValidationErrors.LANGUAGEIDGREATERTHANZERO
        },
        languageValidateAsync: {}
      }
    };

validate.async({
        timezoneId: fpreferencesDS.timezoneId,
        languageId: fpreferencesDS.languageId
      }, constraints).then(() => {
        next();
      }, errors => {
        console.log(errors);
        return;
      });

Если я закомментирую валидатор timezoneValidateAsync, ошибка языка будет возвращена в виде переменной errors. Если я закомментирую languageValidateAsync, ошибка часового пояса возвращается нормально. Если я оставлю их обоих без комментариев, будет получен следующий необработанный отказ от обещания:

(узел: 25280) UnhandledPromiseRejectionWarning: # (узел: 25280) UnhandledPromiseRejectionWarning: необработанное отклонение обещания. это ошибка возникла либо при броске внутри асинхронной функции без блокировки, или отклонив обещание, которое не было обработано с .catch (). (идентификатор отклонения: 1) (узел: 25280) [DEP0018] DeprecationWarning: Отклонения необработанных обещаний устарели. В будущее, обещания отклонения, которые не обрабатываются, прекратят Процесс Node.js с ненулевым кодом выхода.

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

1 Ответ

0 голосов
/ 01 ноября 2018

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

if (!timezone) {
   resolve(ValidationErrors.NOSUCHTIMEZONE);
   return;
}

вместо

if (!timezone) {
   reject(ValidationErrors.NOSUCHTIMEZONE);
   return;
}
...