I am completely new to AWS and serverless etc. To speed up development I would like the ability to debug my application locally.
Following this article Running and Debugging AWS Lambda functions locally I have attempted to achieve just that.
In Visual Studio Code when I run the debug configuration, the application exits instantly without error (A break-point is set on the declaration and initialisation of the 'content' variable). I am not sure I have the function name correct. I am trying to enter at the main 'handler' function defined in 'index.js' as:
exports.handler = (event, context, callBack) =>
{
let bIsPostRequest = false, bIsPutRequest = false, bIsGetRequest = false, bIsDelRequest = false;
let content = "";
...
Here is my 'launch.json' configuration file:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Debugger",
"program":
"${workspaceFolder}\\node_modules\\serverless\\bin\\serverless",
"args":[
"invoke",
"local",
"-f",
"index.handler", // function name
"--data",
"{}"
],
"outFiles": [
"${workspaceFolder}\\index.js"
]
}
]
}
Also, I am not 100% certain on the definition of 'outfiles' in the configuration. I have come to the conclusion it is the file(s) I am trying to debug, however if this is the case 'outfiles' does not seem a fitting name to me.
The local environment I am working in is a windows one.
After coming across this post I managed to get the debugger working. Here is the configuration to match my needs:
const lambdaLocal = require('lambda-local');
var lambdaFunc = require("./index.js");
lambdaLocal.execute({
lambdaFunc: lambdaFunc,
lambdaHandler: "handler",
event: {
context: {
"resource-path": "/products",
"http-method": "GET"
},
"body-json": {
name : "ProductA"
}
}
}).then(function(done) {
console.log(done);
}).catch(function(err) {
console.log(err);
});
I saved this file as 'debugLocal.js' in my main working directory. The launch.json file now looks as follows:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Debugger",
"program": "${workspaceFolder}\\debugLocal.js"
}
]
}
So far everything appears to be replicated fairly well. One thing to note is the file paths on includes had to be changed slightly i.e. require("./js/inc/globalDefines.js"); instead of require("js/inc/globalDefines.js");
Related
I am currently developing a couple of node js function apps in the same project that I would like to be able to debug together. After some effort I was able to run them without a debugger with compounds. And it kinda works since all functions are running although im only able to see output from one at a time.
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Func1",
"type": "node",
"request": "launch",
"port": 9000,
"preLaunchTask": "npm: start - func1"
},
{
"name": "Func2",
"type": "node",
"request": "launch",
"port": 9001,
"preLaunchTask": "npm: start - func2"
}
],
"compounds": [
{
"name": "Compound",
"configurations": [
"Func1",
"Func2"
]
}
]
}
tasks.json
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "start",
"path": "func1/",
"problemMatcher": [],
"label": "npm: start - func1",
"detail": "func start"
},
{
"type": "npm",
"script": "start",
"path": "func2/",
"problemMatcher": [],
"label": "npm: start - func2",
"detail": "func start"
}
]
}
I have also tried different configurations in tasks.json and launch.json using func start with moderate success and I have been able to attach a single function app to debugger while starting the rest.
"type": "func",
"label": "func: start - func1"
"command": "host start",
"problemMatcher": "$func-node-watch",
"isBackground": true,
"dependsOn": "npm: install - func1",
"options": {
"cwd": "${workspaceFolder}/func1"
}
But when I attempt to add a second one with another label it is only able to recognize one of them and the launch of the other app receives error "Could not find the task 'func: start - func2'".
My questions are if it is possible to have multiple Function App attached to debugger and in that case how? Would it also be possible to get the logs in the same output terminal or multiple terminals for each Function App. I know that both can be achived in Visual Studio with c# but is it possible in VS Code with Node.
I am currently developing a couple of node js function apps in the
same project
1, If your function app here refers to Trigger, then the default settings of VS Code should be able to be achieved (unprocessed functions will be in a waiting state, but every place marked with a breakpoint will be executed, but you cannot be in different at the same time Breakpoints).
2, If your function app here refers to a standalone app, then the key is the port. Below settings can change the default port of function app on local:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"FUNCTIONS_WORKER_RUNTIME": "python"
},
"Host": {
"LocalHttpPort": 5861,
"CORS": "*",
"CORSCredentials": false
}
}
After the above settings, you can start two VS Code programs Debug different function app at the same time without causing conflicts.
Im trying to get vscode debugger to work with an application generated with AWS Sam, but with TypeScript.
So before I added TypeScript, the debugger worked fine, I could reach the breakpoints without issue.
When I added TypeScript, I had to change to folder structure, by adding a src and dist folder, so currently my file structure is like this:
According to AWS documentation (page 58): https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/aws-tookit-vscode-ug.pdf
I think it has to do with the pathMappings in the launch.json file, but I can't seem to figure out what would the correct path. This is my current launch.json file:
{
"configurations": [
{
"type": "aws-sam",
"request": "direct-invoke",
"name": "puppeteer-pdfMerger:HelloWorldFunction",
"invokeTarget": {
"target": "template",
"templatePath": "puppeteer-pdfMerger/template.yaml",
"logicalId": "HelloWorldFunction"
},
"lambda": {
"runtime": "nodejs12.x",
"payload": {},
"environmentVariables": {},
"pathMappings": [{
"localRoot": "${workspaceFolder}/puppeteer-pdfMerger/hello-world/dist/HelloWorldFunction",
"remoteRoot": "/var/task/dist"
}]
}
}
}
I will note that when running this configuration the containerized Lambda runs fine, it's just the breakpoints are not working.
I managed to get the breakpoints to work in the end.
What ended up working for me was changing the Dockerfile to:
FROM public.ecr.aws/lambda/nodejs:12
COPY dist/*.js package.json ./
RUN npm install
# Command can be overwritten by providing a different command in the template directly.
CMD ["app.lambdaHandler"]
And having the launch.json config as follows:
{
"type": "aws-sam",
"request": "direct-invoke",
"name": "puppeteer-pdfMerger:PdfGeneratorAndMergerFunction TemplateTarget",
"invokeTarget": {
"target": "template",
"templatePath": "puppeteer-pdfMerger/template.yaml",
"logicalId": "PdfGeneratorAndMergerFunction"
},
"lambda": {
"runtime": "nodejs12.x",
"payload": {},
"environmentVariables": {},
"pathMappings": [
{
"localRoot": "${workspaceRoot}/puppeteer-pdfMerger/hello-world/dist",
"remoteRoot": "/var/task"
}
]
}
}
I have seen lots of answer of how to debug a lambda function offline in vscode and I have got that working, to the extent I can set breakpoint and step through it.
However I am unsure how to specify the payload input for the lambda function for testing.
{
"configurations": [
{
"type": "aws-sam",
"request": "direct-invoke",
"name": "Downloads:charge.handler (nodejs10.x)",
"invokeTarget": {
"target": "code",
"projectRoot": "",
"lambdaHandler": "charge.handler"
},
"lambda": {
"runtime": "nodejs10.x",
"payload": {},
"environmentVariables": {}
}
}
]
}
It seems whatever I put into the payload json field, I only ever see an empty param object when my lambda function runs. I also have an ssm key saved on the aws server. Will that automatically be available to my locally debugged lambda function which I have setup with with SAM CLI, Docker and AWS CLI?
Any help would be greatly appreciated.
Thanks,
Greg
Okay so I wasn't specifying the payload properly.
Should be:
"payload": { "json": { "body": {
"item1": 1, "item2": 2, ...
}}}
I would like to debug my typescript code (which runs in NodeJS) with VSCode.
The following code is my starting point and works just fine.
Typescript code:
//src/index.ts
console.log('line 1');
console.log('line 2');
The compiler settings:
//tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"sourceMap": true
},
"exclude": [
"node_modules"
]
}
And the launch configuration
//.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}/src/index.js"
}
]
}
In the above setup, I can add breakpoints in the typescript code and then start debugging.
All typescript source code is in a directory called src/. I would like to specify this in the compiler settings by adding the following config option:
"compilerOptions": {
//...
"sourceRoot": "src"
It still compiles just fine and when executed, it prints "line 1", "line 2".
However, the breakpoints no longer work. I looked at the generated sourcemaps and they specify a path "sourceRoot":"src". I guess that this breaks the sourcemap lookup. Since the original sources are in the same folder as the generated output.
How do I configure this correctly in the compiler?
The easiest way I have found to debug ts in vscode is to use ts-node
Then I use ts-node in my launch script as so
{
"version": "0.2.0",
"configurations": [
{
"name": "ts node inspector",
"type": "node",
"request": "launch",
"args": ["${workspaceRoot}/src/server.ts"],
"runtimeArgs": ["-r", "ts-node/register"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"internalConsoleOptions": "openOnSessionStart",
"env": {
"TS_NODE_IGNORE": "false"
}
}
]
}
The documentation explains that sourceRoot:
Specifies the location where debugger should locate TypeScript files
instead of source locations. Use this flag if the sources will be
located at run-time in a different location than that at design-time.
The location specified will be embedded in the sourceMap to direct the
debugger where the source files will be located.
So I have been using it incorrectly.
My breakpoints in VS code keep jumping - I am using node.JS and when I run the debugger my breakpoint goes from line 30 approximately to line 130 or so at the bottom of the file with the export function.
The project I am working on is a service layer so it is pretty much all async.
async superspecficfunnamedoeshere(blah, accessToken) {
console.log('example')
Breakpoint goes on above line^
Bunch more code goes here, here is the function etc , the breakpoint is just under the function declaration
}
}
export thing from thing
^^ breakpoint moves to bottom export statement.
Putting a breakpoint in this console.log line just completely skips the entire function and goes to the export statement at the bottom.
Here is my launch.json- at first it was failing at the import statement until I configured it to work with babel:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "thing1",
"program": "${workspaceFolder}/src/app.js",
"protocol": "inspector",
"runtimeArgs": [
"--harmony",
],
"cwd": "${workspaceRoot}",
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/babel-node",
"envFile": "${workspaceFolder}/.env",
"outFiles": [ "${workspaceFolder}/bin/**/*.js" ],
}
]
}
lastly here is my babel config
{ "env": {
"development": {
"sourceMaps": true,
"retainLines": true
}
},
"presets": [
[
"#babel/preset-env",
{
"targets": {
"node": "current"
}
}
]
]
}
How can I get debugging async functions to work?
I've already tried going through the vs code docs, and I'm a little confused on how source maps work. But I have implemented some of the suggestions there.
There is no error message just the breakpoint moving to the end of the file from the console.log line where the breakpoint is much earlier (without anything to show for it)