我正在尝试将 SES 发送函数从我的 API 服务器移动到 lambda 函数,SES 在 API 服务器中工作正常,但在 lambda 中不行。
这是设置
这是其他相关信息
这是代码
import { SESClient, SendEmailCommand } from "@aws-sdk/client-ses";
const sesClient = new SESClient({ region: "us-west-2" });
export const handler = async (event) => {
event.Records.forEach( async (msg) => {
const args = JSON.parse(msg.body);
const command = new SendEmailCommand ({
Source: (args.senderEmailAddr || process.env.DEFAULT_SENDER_ADDRESS),
Destination: { ToAddresses: [args.recipientEmailAddr] },
Message: {
Body: { Text: { Data: args.emailContents } },
Subject: { Data: args.subject },
},
});
try {
const resp = await sesClient.send(command);
console.log('++++++++++++++++++++++++++++++++');
console.log(`Email send response ${resp}`);
return resp;
} catch(err) {
console.log(`Failed to send email - ${err}`);
}
});
};
lambda 运行并退出,没有任何错误,但是,它从不执行 sesClient.send() 命令之后的行
console.log('++++++++++++++++++++++++++++++++');
这告诉我该函数在执行 sesClient.send() 调用期间终止(如果我将控制台语句放在 sesClient.send() 之前,它们会显示在 cloudwatch 日志中。
这是 cloudwatch 命令的输出
INIT_START Runtime Version: nodejs:18.v10 Runtime Version ARN: arn:aws:lambda:us-west-2::runtime:e3aaabf6b92ef8755eaae2f4bfdcb7eb8c4536a5e044900570a42bdba7b869d9
START RequestId: c0a8e260-7149-5934-9246-bf3cc1af54ff Version: $LATEST
END RequestId: c0a8e260-7149-5934-9246-bf3cc1af54ff
REPORT RequestId: c0a8e260-7149-5934-9246-bf3cc1af54ff Duration: 371.10 ms Billed Duration: 372 ms Memory Size: 128 MB Max Memory Used: 95 MB Init Duration: 587.21 ms
any idea of what I am doing wrong here??
在 AWS Lambda 中处理异步代码时存在一个常见问题。代码中的关键问题是将
forEach
与异步函数一起使用。 Lambda 不会等待 forEach
循环中的所有异步操作完成才终止。
结果是 Lambda 函数在启动异步操作后立即完成,而无需等待它们完成。这可能就是您在
sesClient.send()
行之后看不到日志的原因。
要解决此问题,您应该使用
Promise.all
或等待每封电子邮件发送后再继续的循环:
以下是如何修改处理程序以等待使用
Promise.all
发送所有电子邮件:
export const handler = async (event) => {
const promises = event.Records.map(async (msg) => {
const args = JSON.parse(msg.body);
const command = new SendEmailCommand({
Source: (args.senderEmailAddr || process.env.DEFAULT_SENDER_ADDRESS),
Destination: { ToAddresses: [args.recipientEmailAddr] },
Message: {
Body: { Text: { Data: args.emailContents } },
Subject: { Data: args.subject },
},
});
try {
const resp = await sesClient.send(command);
console.log(`Email send response ${resp}`);
return resp;
} catch (err) {
console.log(`Failed to send email - ${err}`);
}
});
await Promise.all(promises);
console.log('++++++++++++++++++++++++++++++++');
};
现在,Lambda 函数将等待所有电子邮件发送完成,您应该在发送电子邮件后看到日志。