javascript - Lambda 忘记如何解释 JavaScript?

标签 javascript typescript aws-lambda

我在 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/

相关文章:

java - aws lambda 测试控制台中的 config.properties 出现 FileNotFoundException

amazon-web-services - 在AWS云形成模板中如何根据环境将策略附加到角色

javascript - 如何将日期选择器添加到没有显示的 div 中的文本框?

angular - 素NG : get value of all the p-dropdown on change event of one drop down

angular - 如何处理 Angular 8 中的 View 子静态错误

aws-lambda - 在参数 ZipFile AWS::Lambda::Function 上上传本地文件

javascript - 为什么这段 JS 代码会失败?

javascript - 添加空系列会更改轴最小值

javascript - 如何将 JWT 身份验证与 Web API 集成?

node.js - 在 angular2 应用程序中运行 ng serve 时出现错误 'Cannot read property ' length' of undefined'