代码之家  ›  专栏  ›  技术社区  ›  GridDragon

Lambda忘记了如何解释JavaScript?

  •  0
  • GridDragon  · 技术社区  · 6 年前

    我在兰达发生了一件很奇怪的事。我有一个解释字符串输入的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
    

    配置/环境详细信息

    • 手写体
    • 由tsc使用Typescript 8.3.0编写
    • 使用无服务器框架部署
    • Lambda Runtime:Node.js 12.x(也在Node 10中运行,但升级到12尝试修复此问题)
    1 回复  |  直到 6 年前
        1
  •  3
  •   Jacob    6 年前

    这个错误意味着 params 是一个 String ,不是对象。也许你的 message 是双编码的JSON字符串(包含JSON字符串的JSON字符串)。我不知道它是怎么来的,但要找一个逻辑 JSON.stringify 关于已经是JSON的东西。或者如@Titus所说,做双重解码:

    const params = JSON.parse(JSON.parse(message));
    
    推荐文章