Reputation: 53
I am using mail-confirm to validate an email address and the Lambda function is returning rather than waiting for the promise result on
email.check().then(results=>{
And jumps straight to
console.log('callback issue');
and returns. I would expect the email check to finish and return the results object inside of the callback. Instead the function is returned before the promise can resolve. Any pointers will be appreciated.
Function example:
const MailConfirm = require('mail-confirm');
const isemail = require('isemail');
module.exports.app = async (event, context) => {
let request = JSON.parse(event.body)
if(request.email){
var emailToValidate = request.email
if(isemail.validate(emailToValidate)){
console.log(`${emailToValidate} - stage 1 pass`);
const email = new MailConfirm({
emailAddress: emailToValidate,
timeout: 2000,
invalidMailboxKeywords: ['noreply', 'noemail']
});
//Promise issue
email.check().then(results=>{
console.log(results);
return {
statusCode: 200,
body: JSON.stringify({
validatedEmail: emailToValidate,
isValid: true,
}),
};
}).catch(err=>{
console.log(`${emailToValidate} stage 2/3 failed`)
return {
statusCode: 200,
body: JSON.stringify({
validatedEmail: emailToValidate,
isValid: false,
message: err,
}),
};
});
//Returns here
console.log('callback issue');
}else{
return {
statusCode: 200,
body: JSON.stringify({
validatedEmail: emailToValidate,
isValid: false,
message: 'Failed stage 1 validation',
}),
};
}
}
// return {
// statusCode: 500,
// body: JSON.stringify({
// message: 'Something went wrong.',
// }),
// };
};
EDIT:
Thanks everyone for your responses. I have implemented the await and it is working nicely when testing
. However if i validate
the email.check()
function doesn't return and my lambda function returns with a blank response (502 to API gateway). I am no sure what happens after let results = await email.check();
when validating [email protected]
. My Lambada function is not timing out.
try{
let results = await email.check();
console.log(results);
//Returns ok on [email protected]
return {
statusCode: 200,
body: JSON.stringify({
validatedEmail: emailToValidate,
isValid: true,
}),
};
} catch(err){
console.log(`${emailToValidate} stage 2/3 failed`)
return {
statusCode: 200,
body: JSON.stringify({
validatedEmail: emailToValidate,
isValid: false,
message: err,
}),
};
}
Lambda logs
START Version: $LATEST
[email protected] - stage 1 pass
END
REPORT Duration: 647.88 ms Billed Duration: 700 ms Memory Size: 128 MB Max Memory Used: 21 MB
API Gateway 502 Bad Gateway (Due to the Lambda function response being null)
{
"message": "Internal server error"
}
EDIT 2:
It turns out i am getting a 554 error in mail-confirm
when validating [email protected]
.
Upvotes: 0
Views: 3004
Reputation: 4486
You need to do some reading but basically anything in a async function that returns a promise you can await like so
module.exports.app = async (event, context, callback) => {
try {
const results = await SomeClass.somePromise()
const anotherResult = await SomeOtherClass.somePromise()
// do some stuff
callback(null, some_valid_http_response)
} catch (e) [
callback(e, null) // or handle another way
}
}
In short you dont await somePromise.then you just await the promise.
If you want to save yourself a whole world of hurt switch to Node 8.10 you can use most of the latest ES6 features, just make sure you use:
const someLib = require('whatever)
rather than import!
Upvotes: 1
Reputation:
Your function is async, email.check().then(...)
returns a promise which is never awaited on your side. Remove async at your lambda handler or await await email.check().then(...)
the returned promise. If you remove async you have to use the callback property of lambda.
Upvotes: 0