我在 Lambda 中发生了一些非常奇怪的事情。我有一个 JS 函数来解释字符串输入。该代码由单元测试覆盖,以确认验证逻辑是否按预期工作。但一旦部署到 Lambda,我就会得到不同的行为。是否真的存在我忽略的菜鸟错误。或者 Lambda 中是否有某些设置可以解释为什么我的代码被不同地解释。
这是我的功能:
public async processMessage(message: string): Promise<void> {
logger.info(`Message: ${message}`);
const params = JSON.parse(message);
if ('fileId' in params && 'location' in params && 'fileType' in params) {
return this.fileLoader.load(params.fileId, params.location, fromString(params.fileType));
} else {
throw new InvalidArgumentError('A required field on the message is missing.');
}
}
验证按预期工作,函数被正确调用。一切看起来都很棒! 然后我将其部署到 lambda 并在那里调用它。我收到此错误:
Cannot use 'in' operator to search for 'fileId' in {\"fileId\":\"1234\",\"fileType\": \"TEST_FILE\",\"location\": \"https://d4-file-proc-staging.s3.amazonaws.com/testFile.csv\"}
这是 CloudWatch 日志:
Message: "{\"fileId\":\"1234\",\"fileType\": \"TEST_FILE\",\"location\": \"https://d4-file-proc-staging.s3.amazonaws.com/testFile.csv\"}"
ERROR Unhandled Promise Rejection
{
"errorType": "Runtime.UnhandledPromiseRejection",
"errorMessage": "TypeError: Cannot use 'in' operator to search for 'fileId' in {\"fileId\":\"1234\",\"fileType\": \"TEST_FILE\",\"location\": \"https://d4-file-proc-staging.s3.amazonaws.com/testFile.csv\"}",
"reason": {
"errorType": "TypeError",
"errorMessage": "Cannot use 'in' operator to search for 'fileId' in {\"fileId\":\"1234\",\"fileType\": \"TEST_FILE\",\"location\": \"https://d4-file-proc-staging.s3.amazonaws.com/testFile.csv\"}",
"stack": [
"TypeError: Cannot use 'in' operator to search for 'fileId' in {\"fileId\":\"1234\",\"fileType\": \"TEST_FILE\",\"location\": \"https://d4-file-proc-staging.s3.amazonaws.com/testFile.csv\"}",
" at FileLoaderMessageHandler.processMessage (/var/task/dist/infrastructure/fileLoaderMessageHandler.js:14:22)",
" at /var/task/dist/aws/fileLoader.js:23:57",
" at Array.forEach (<anonymous>)",
" at Runtime.exports.handle [as handler] (/var/task/dist/aws/fileLoader.js:23:18)",
" at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
]
},
"promise": {},
"stack": [
"Runtime.UnhandledPromiseRejection: TypeError: Cannot use 'in' operator to search for 'fileId' in {\"fileId\":\"1234\",\"fileType\": \"TEST_FILE\",\"location\": \"https://d4-file-proc-staging.s3.amazonaws.com/testFile.csv\"}",
" at process.<anonymous> (/var/runtime/index.js:35:15)",
" at process.emit (events.js:210:5)",
" at process.EventEmitter.emit (domain.js:476:20)",
" at processPromiseRejections (internal/process/promises.js:201:33)",
" at processTicksAndRejections (internal/process/task_queues.js:94:32)"
]
}
我尝试重构它以使用 Object.keys 。但它的表现仍然很奇怪。
function isFileLoaderParams(params: any): params is FileLoaderParams {
logger.info(`INPUT: ${params}`);
if (!params.fileId) {
logger.warn('FileId not found');
logger.info(`DoubleCheck: ${JSON.stringify(params)}`);
logger.info(`Value Is: ${JSON.stringify(params.fileId)}`);
logger.info(`ArrayAccess?: ${JSON.stringify(params['fileId'])}`);
return false;
}
if (!params.location) {
logger.warn('Location not found');
return false;
}
if (!params.fileType) {
logger.warn('FileType not found');
return false;
}
return true;
}
生成此输出:
INPUT: {"fileId":"1234","fileType": "TEST_FILE","location": "https://d4-file-proc-staging.s3.amazonaws.com/testFile.csv"}
FileId not found
DoubleCheck: "{\"fileId\":\"1234\",\"fileType\": \"TEST_FILE\",\"location\": \"https://d4-file-proc-staging.s3.amazonaws.com/testFile.csv\"}"
Value Is: undefined
ArrayAccess?: undefined
配置/环境详细信息
- 用 typescript 编写
- 由 tsc 使用 Typescript 8.3.0 编译
- 使用无服务器框架部署
- Lambda 运行时:Node.js 12.x(也在 Node 10 中运行,但升级到 12 试图修复此问题)
最佳答案
该错误意味着 params
是一个 String
,而不是一个对象。也许您的消息是双重编码的 JSON 字符串(包含 JSON 字符串的 JSON 字符串)。我不确定它是如何到达那里的,但是寻找对已经是 JSON 的东西执行 JSON.stringify
的逻辑。或者正如 @Titus 提到的,进行双重解码:
const params = JSON.parse(JSON.parse(message));
关于javascript - Lambda 忘记如何解释 JavaScript?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59327928/