AWS Lambda [Node.js 4.3] - 奇怪的堆栈跟踪

时间:2017-09-06 14:44:41

标签: javascript node.js amazon-web-services lambda

我们正在用AWS编写node.js 4.3 lambda函数,但是我们遇到了一个奇怪的behaviour并抛出错误。

首先:

'use strict'; 
   
exports.handler = function(event, context, callback) {
    throw new Error();
};

这就像预期的那样:

 at exports.handler (/var/task/TestCode.js:4:11)

但是如果我们添加一个函数(甚至是未调用的),它调用一个不同类/ obj的函数,其中包含带有obj的lambda表达式,我们得到一个神秘的抛出信息。 为了使事情更容易理解,这里有一些代码:

'use strict';

function aRandomFunction() {
    something.foo((obj) => {});
}
    
exports.handler = function(event, context, callback) {
    throw new Error();
};

现在我们得到一个日志,我们不明白为什么:

 at something.foo.exports.handler (/var/task/TestCode.js:8:11)

有人可以解释一下为什么会这样吗?这似乎是我不理解的一些JS魔法:)

由于

1 个答案:

答案 0 :(得分:1)

修订后的答案 - 升级到v6.1

您的问题是Node版本4.3。升级到6.1将解决问题。

我重新创建了您提供的代码段,并在两个环境中运行它。两种情况分别给出以下错误。

  • 4.3

    • at something.foo.module.exports.test (/var/task/handler.js:56:10)
    • 意外结果。
  • 6.1

    • at module.exports.test (/var/task/handler.js:56:10)
    • 这将是投掷的预期结果。

原始答案 - polyfill

您的问题是错误消息中引用的行上的箭头函数...



'use strict';

function aRandomFunction() {
    something.foo((obj) => {});  // illegal arrow function (ES6 not supported in Lambda environment by default)
}

exports.handler = function(event, context, callback) {
    throw new Error();
};




没有polyfill的Lambda节点环境不支持ES6 - 即使在传统Node环境中的^ 4.0中也支持ES6。这是因为AWS Lambda不使用完整且最新的Node引擎代码库。它最初是为较小的用例(例如Alexa技能集和单个函数调用)设计的,因此"额外的"特征被削减 - 大部分ES6都是受害者之一。

对于polyfill,我推荐babel。

解决方案:

  1. 安装相关的babel包。 (参见package.json以供参考)

  2. 将以下行添加到handler.js的顶部 - 应该执行此操作 特技。

  3. 
    
    'use strict';
    if (!global._babelPolyfill) require('babel-polyfill');  // insert polyfill assignment
    
    function aRandomFunction() {
        something.foo((obj) => {});
    }
    
    exports.handler = function(event, context, callback) {
        throw new Error();
    };
    
    
    

    
    
    // package.json (not a valid comment)
    "dependencies": {
        "babel-polyfill": "^6.23.0",
        "babel-runtime": "^6.23.0",
      },
      "devDependencies": {
        "babel-core": "^6.24.1",
        "babel-loader": "^7.0.0",
        "babel-plugin-transform-runtime": "^6.23.0",
        "babel-preset-es2015": "^6.24.1",
        "babel-preset-es2016": "^6.24.1",
        "babel-preset-stage-0": "^6.24.1",
        "json-loader": "^0.5.4",
        "serverless-webpack": "^1.0.0-rc.4",
        "webpack": "^2.4.1",
        "webpack-node-externals": "^1.6.0"
      }
    
    
    

    如果你使用无服务器这样的框架,那么这里webpack.config.jsserverless.yml

    
    
    // webpack.config.js
    const nodeExternals = require('webpack-node-externals');
    
    module.exports = {
      entry: './handler.js',
      target: 'node',
      module: {
        loaders: [{
          test: /\.jsx?$/,
          loader: 'babel-loader',  // add babel-loader
          include: __dirname,
          exclude: /node_modules/,
        }, {
          test: /\.json$/,
          loader: 'json-loader',
        }],
      },
      externals: [nodeExternals()],
    };
    
    
    

    
    
      # serverless.yml
      service: myApp
    
      package:
        exclude:
    
      provider:
        name: aws
        runtime: nodejs4.3
        stage: development
        region: ap-northeast-1
    
      plugins:
        - serverless-webpack
    
      custom:
        webpackIncludeModules: true
        main:
          babelOptions:                         # include babel options
            presets: [es2015, es2016, stage-0]
            plugins: [transform-runtime]
    
      functions:
        main:
          handler: handler.main
          memorySize: 1024
          timeout: 10
          events:
            - http: