简体   繁体   中英

NodeJS + Validate.js multiple async validators

I'm kinda new to NodeJS and I'm trying to use custom async validators for two of the fields. The reason why I'm using an async validator is that a request must be made to the database to check if a record with that id already exists. I implemented two validators (code listed below) - if I use only one of them in the validate.async constraints, each of them work. However, if I use both of them at the same time, an unhandled promise rejection (exact error also below) is thrown and only the first validator's error is returned.

Code: 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;

Usage in 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;
      });

If I comment out the timezoneValidateAsync validator, the language error is returned fine in the errors variable. If I comment out the languageValidateAsync, the timezone error is returned fine. If I leave them both uncommented, the following unhandled promise rejection is thrown:

(node:25280) UnhandledPromiseRejectionWarning: # (node:25280) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) (node:25280) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

I guess my mistake is somehow in chaining those promises, but I don't really have idea how to do it (if I'm right at all). I'm open to any suggestions, ideas and pointers.

I found my mistake, it turns out that I shouldn't the promise reject in case of an error. Instead, I should resolve it with the error message. Example (for both of the validators):

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

instead of

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM