Reputation: 103
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.
Upvotes: 0
Views: 1071
Reputation: 103
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;
}
Upvotes: 1