Serverless invoke local无响应:Node.js Lambda本地调试问题求助
先帮你理清--function参数的困惑,再一步步排查调试无反应的问题:
关于--function参数的疑问
--function or -f The name of the function in your service that you want to invoke locally. Required.
这个参数指的是你在serverless.yml配置文件中定义的函数名称,不是你代码里导出的handler函数名。举个例子,如果你的serverless.yml里是这样写的:
functions: hello: # 这就是--function要指定的名称 handler: handler.handler # 这里的handler.handler才是代码里导出的handler函数(文件handler.js里的exports.handler)
那你在invoke local时用--function hello就是正确的,和你代码里导出的函数名(handler)无关。你之前用--function hello是没问题的,只要yml里对应的函数存在就行。
调试无反应、无法进入函数的排查步骤
1. 先确认Serverless本地调用本身是否能运行
先脱离VSCode调试,直接在终端执行命令:
sls invoke local --function hello --data '{"triggerSource": "你的CONSTANTS.TRIGGER_SOURCE值", "request": {"userAttributes": {"你的USER_ATTRIBUTES键": "test"}, "codeParameter": "123"}}'
如果这个命令也没输出,那问题出在Serverless配置或代码逻辑上;如果有输出,再回到VSCode调试配置的问题。
2. 检查代码逻辑的分支问题
看你的handler代码:
module.exports.handler = (event, context, callback) => { if (event.triggerSource === CONSTANTS.TRIGGER_SOURCE) { // 主逻辑 } else { context.done(null, event); } };
你传入的--data "hello world"是一个字符串,解析后的event就是"hello world",根本没有triggerSource字段,所以代码直接走到else分支,调用context.done(null, event)就结束了,自然看不到日志也进不了主逻辑的断点。
你需要传入符合handler预期的JSON格式数据,比如:
--data '{"triggerSource": "PostConfirmation_ConfirmSignUp", "request": {"userAttributes": {"email": "test@example.com"}, "codeParameter": "123456"}}'
(替换成你CONSTANTS里对应的实际值)
另外,代码里还有个小错误:console.log("URI = " + url);这里你定义的变量是uri,但写的是url,会抛出ReferenceError,这个也要修正。
3. 优化VSCode调试配置
你的launch.json可能存在路径兼容问题,尤其是Windows系统下,node_modules/.bin/sls可能无法正确执行。建议修改成直接调用Serverless的入口脚本:
{ "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Launch Local Lambda", "program": "${workspaceFolder}/node_modules/serverless/bin/serverless.js", "args": [ "invoke", "local", "--function", "hello", "--data", "{\"triggerSource\": \"你的TRIGGER_SOURCE值\", \"request\": {\"userAttributes\": {\"你的USER_ATTRIBUTES键\": \"testuser\"}, \"codeParameter\": \"123456\"}}" ], "console": "integratedTerminal", "stopOnEntry": false, "outputCapture": "std" } ] }
- 用
serverless.js代替.bin/sls,跨系统兼容性更好; console: integratedTerminal能让你直接在VSCode终端看到Serverless的输出;- 把
--data改成符合逻辑的JSON字符串(注意转义双引号)。
4. 处理异步逻辑(如果getUrlData是异步的)
如果getUrlData是异步函数(比如调用HTTP接口),你当前的代码里调用完getUrlData就直接结束了,不会等待它执行完成。需要在getUrlData的回调里调用context.done,比如:
getUrlData(uri, country, username, codeP, (err, result) => { if (err) { context.done(err); } else { context.done(null, result); } });
否则函数会提前退出,看不到异步操作的日志。
内容的提问来源于stack exchange,提问作者Jorge Belano Murphy

