【发布时间】:2018-09-28 09:27:22
【问题描述】:
最近,AWS 宣布为其 lambda 函数 (Node.js 8.10 runtime available) 提供 nodejs8.10 运行时。虽然这对于快乐的流程来说似乎很棒,但我在不快乐的流程中遇到了一些问题,即我收到了“UnhandledPromiseRejectionWarnings”。
我正在使用以下代码。这个想法是我提供了一个不存在的对象的密钥来测试该场景的不愉快流程。我的目标是让错误被记录并传播到 lambda 之外,因为我在这里没有理智的方法来处理它(我无法在这个 lambda 函数中检索新键)。我也希望能够在调用者中使用错误(例如另一个 lambda 函数或步进函数)。
'use strict';
const AWS = require('aws-sdk');
exports.handler = async (event) => {
let data;
try {
data = await getObject(event.key);
} catch (err) {
console.error('So this happened:', err);
throw err;
}
return data;
}
const getObject = async (key) => {
let params = {
Bucket: process.env.BUCKET,
Key: key
};
const s3 = new AWS.S3();
let data;
try {
data = await s3.getObject(params).promise();
} catch(err) {
console.log('Error retrieving object');
throw err;
}
console.log('Retrieved data');
return data.Body.toString('utf8');
}
如果我运行这个 lambda 函数(使用 SAM local),我会像我想要的那样从 lambda 中得到错误,但我也会收到以下警告:
2018-04-18T07:54:16.217Z 6ecc84eb-46f6-1b08-23fb-46de7c5ba6eb (node:1) UnhandledPromiseRejectionWarning: NoSuchKey: The specified key does not exist.
at Request.extractError (/var/task/node_modules/aws-sdk/lib/services/s3.js:577:35)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
2018-04-18T07:54:16.218Z 6ecc84eb-46f6-1b08-23fb-46de7c5ba6eb (node:1) 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)
2018-04-18T07:54:16.218Z 6ecc84eb-46f6-1b08-23fb-46de7c5ba6eb (node:1) [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.
我不确定如何处理这个问题,同时仍然将错误从 lambda 函数中传播出来(根据lambda function errors (node.js),这应该是一个有效的场景)
我也尝试过运行类似(对我而言)的场景,例如下面的场景(尝试查明并理解错误),但不知何故,在这里我没有收到警告,它按预期工作(返回错误来自 lambda 函数)。
'use strict';
const AWS = require('aws-sdk');
exports.handler = async (event) => {
let data;
try {
data = await directBoom();
} catch (err) {
console.error('So this happened:', err);
throw err;
}
return data;
}
const directBoom = async () => {
let data;
try {
data = await Promise.reject(new Error('boom!'));
} catch(err) {
throw err;
}
return data;
}
我在这里遗漏了什么,为什么这两个示例的行为不同?如何摆脱第一个示例中的警告,同时仍然能够将错误传播到 lambda 函数之外?任何帮助将不胜感激。
【问题讨论】:
-
我遇到了同样的问题。 Node 8.10 运行时的 AWS 博客仅返回 Promises,请参阅 amzn.to/2J1Y49r,但他们没有讨论如何处理拒绝。真的很奇怪。或许可以在 AWS 官方论坛上提问?
-
刚刚在AWS官方论坛上发了一个关于这个话题的问题:amzn.to/2JpoHEY
-
我的最小测试按预期工作
exports.handler = async (event) => { throw Error('rejected') };。 lambda 因我的拒绝错误而失败。这可能是一个山姆错误 -
嗯,您的最小测试仍然会导致未处理的承诺拒绝。
-
@MartinDonath 您确定您使用的是 nodejs 8.10 运行时吗? SAM 中的错误是本地的吗?
标签: node.js async-await aws-lambda