У меня есть функция AWS Lambda, обслуживаемая через шлюз API AWS.Кажется, все работает нормально по большей части.Есть одна функция нашего API, которая работает неправильно.Это веб-крючок, который получает входящие факсы и электронные письма, чтобы мы знали, что они пришли.
Мы проверили все, и это прекрасно работает на нашей локальной машине и даже на провайдерах, таких как линодеили цифровой океан.Наша проблема заключается только в том, что при развертывании с AWS Lambda.
- Я пытался увеличить пределы памяти и выполнения намного выше того, что требуется.
- Я пробовал с несколькими методами и библиотеками электронной почты.
- Я пробовал использовать различные форматы функций.
В журналах облачного наблюдения за лямбдой отображается console.log(req.body.MediaUrl);
, но на stdout или stderr нет других выходных данных.Даже если я добавлю очевидные недостатки, ошибок не будет.Это почти так, как будто функция молча терпит неудачу без объяснения причин.
Я смог заставить его работать, если я отправил 2-3 почтовых запроса в течение 1-2 секунд после другого.1, может быть, 2 письма будут отправлены, но не все из них.Если один почтовый запрос отправляется в обычном режиме, вы никогда не получите письмо.
// Define a handler for when the fax is initially sent
const nodemailer = require('nodemailer');
const aws = require('aws-sdk');
// Start Email Logic
// AWS access keys are built into Lambda, modify permissions of the executor role
aws.config.update({region: 'us-west-2'});
let transporter = nodemailer.createTransport({
SES: new aws.SES({
apiVersion: '2010-12-01',
}),
});
exports.received = function(req, res) {
transporter.sendMail({
from: '"Fax" <fax@domain.com>',
to: process.env.FAX_ADDRESS,
subject: 'A new fax from ' + req.body.From,
text: 'You can view the fax at this url:\n\n' + req.body.MediaUrl,
}, (err, info) => {
if (err) {
console.log(err);
} else {
console.log(info.envelope);
console.log(info.messageId);
console.log('Email Sent');
}
});
// log the URL of the PDF received in the fax just in case email fails
console.log(req.body.MediaUrl);
res.status(200);
res.send();
};
Кстати, в приведенном выше коде есть еще один файл со всеми необходимыми экспресс-пунктами для правильного обслуживания.Опять же, он отлично работает на локальных, других серверах и даже иногда при затоплении лямбды;хотя он никогда не работает последовательно на Lambda.
Я думаю, либо я идиот, которому нужно спать, либо я что-то упускаю из-за Lambda.Может кто-нибудь пролить свет на то, что мне не хватает?
РЕДАКТИРОВАТЬ:
Благодаря Майклу и Хен все стало на свои места.При работе с Lambda лямбда-функция отключается в тот момент, когда она проходит через основную логику процесса.Он не будет ждать завершения ожидающих асинхронных элементов.Следующее изменение устранило мою проблему при использовании Express с Lambda.
Обратите внимание, что я переместил почтовые функции в конец ответа, а затем переместил статус ответа и отправил его внутрь функции mail.Это один из многих способов, который можно решить, но он приятен и прост для наших нужд.
exports.received = function(req, res) {
// log the URL of the PDF received in the fax just in case email fails
console.log(req.body.MediaUrl);
transporter.sendMail({
from: '"Fax" <fax@domain.com>',
to: process.env.FAX_ADDRESS,
subject: 'A new fax from ' + req.body.From,
text: 'You can view the fax at this url:\n\n' + req.body.MediaUrl,
}, (err, info) => {
if (err) {
console.log(err);
res.status(500);
res.send();
} else {
console.log(info.envelope);
console.log(info.messageId);
console.log('Email Sent');
res.status(200);
res.send();
}
});
};