【问题标题】:AWS Lambda [Node.js 4.3] - Strange Stack TraceAWS Lambda [Node.js 4.3] - 奇怪的堆栈跟踪
【发布时间】:2018-02-15 02:55:04
【问题描述】:

我们正在用node.js 4.3 编写AWS 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魔法我不懂:)

谢谢

【问题讨论】:

  • 堆栈跟踪中还有什么?
  • @Michael-sqlbot 就是这样。仅在 [参见上面的代码] 处出错。但这在 aws lambda 中是正常的。

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


【解决方案1】:

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

您的问题是节点版本 4.3。升级到 6.1 即可解决此问题。

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

  • 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 - 即使在传统节点环境中的 ^4.0 中支持它。这是因为 AWS Lambda 没有使用完整且最新的 Node 引擎代码库。它最初是为较小的用例(例如 Alexa 技能集和单个函数调用)而设计的,因此“额外”功能被取消了 - 大多数 ES6 都是受害者之一。

对于 polyfill,我推荐 babel。

解决方案:

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

  2. 将以下行添加到 handler.js 的顶部 - 应该这样做 把戏。

'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"
  }

如果您使用的是 Serverless 之类的框架,那么这里是 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:

【讨论】:

  • 啊哈,所以如果使用 Lambda 的节点 6.10,而不是 4.3,这应该可以正常工作?
  • @tobiah Lambda 不支持 ES6 是不正确的。部分支持 ES6(更多信息请参见 node.green。Node 4.3 支持箭头函数。您不需要 babelwebpackserverless-webpack 仅用于箭头函数。
  • @dashmug - 对于狂热的 Lambda 用户来说,众所周知的事实是,AWS 的 Node 环境无论是 v6 还是 v4 都没有运行最新的引擎,因为在它的初始设计中,Lambda不考虑用作整个后端,而仅用于微服务(例如 Alexa 技能集),因此对本机 Node 代码库进行了重构,以针对较小的功能用例进行优化。所以对 ES6 的支持被认为是冗长而被取消的。有很多文章记录了这一事实。
  • @Michael-sqlbot 我在所有 Lambda 应用程序中运行 V6,默认情况下不支持 ES6。你需要 polyfill。
  • @TobiahRex 一切都好。正如我之前所说,node.green 是查看每个 Node 版本中可用的 ES2015+ 功能的一个很好的参考。此外,狂热的 Lambda 开发人员知道 Lambda 支持 Node v6.10 而不是 v6.1。此外,michal-sqlbot 不是 OP,拥有 56k 的声誉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多