aws-toolkit-vscode icon indicating copy to clipboard operation
aws-toolkit-vscode copied to clipboard

SAM: debug typescript lambda locally

Open mattsains opened this issue 2 years ago • 20 comments

Problem

When I use esbuild to create a SAM application in typescript, I'm unable to set breakpoints in my typescript code using the direct-invoke vscode debug target.

I receive the following error:

Debugger attached.
Could not read source map for file:///var/task/app.js: ENOENT: no such file or directory, open 'd:\Matt\Documents\coding-projects\algoa-gtfs\generate-gtfs\app.js.map'
2023-03-04T19:23:29.832Z	35b556c5-afc6-4038-9b97-ab49edea2f37	INFO	hello world
END RequestId: 35b556c5-afc6-4038-9b97-ab49edea2f37
REPORT RequestId: 35b556c5-afc6-4038-9b97-ab49edea2f37	Init Duration: 0.09 ms	Duration: 105546.28 ms	Billed Duration: 105547 ms	Memory Size: 128 MB	Max Memory Used: 128 MB	
null

This doesn't make sense because the source map is at D:\Matt\Documents\coding-projects\algoa-gtfs\.aws-sam\build\AlgoaGtfsFunction\app.js.map

Steps to reproduce the issue

  1. Download this commit: https://github.com/mattsains/algoa-gtfs/tree/218f0bfb7cf33302c5bd0b7f0df7bf97aa7fd80b
  2. Open in vscode
  3. set a breakpoint in app.ts
  4. Run sam build
  5. Hit F5

Expected behavior

The debugger should load source maps from D:\Matt\Documents\coding-projects\algoa-gtfs\.aws-sam\build\AlgoaGtfsFunction\app.js.map and the lambda should break at the break point set.

System details (run the AWS: About Toolkit command)

OS: Windows_NT x64 10.0.22621 Visual Studio Code extension host: 1.76.0 AWS Toolkit: 1.63.0 node: 16.14.2 electron: 19.1.11

mattsains avatar Mar 04 '23 19:03 mattsains

We have this issue too.

ffMathy avatar Mar 28 '23 12:03 ffMathy

Can you share the launch config you are using?

Related:

  • https://github.com/aws/aws-toolkit-vscode/issues/2050

justinmk3 avatar Mar 28 '23 14:03 justinmk3

I linked to my entire repo in the original issue body, and the launch.json is here: https://github.com/mattsains/algoa-gtfs/blob/218f0bfb7cf33302c5bd0b7f0df7bf97aa7fd80b/.vscode/launch.json

mattsains avatar Apr 03 '23 17:04 mattsains

+1 Also experiencing this exact issue using: MacOS 13.3.1 SAM 1.81.0 AWS Toolikit 1.70 Node 18.16.0 Docker Desktop 4.18.0

Pulling down a default template, sam init --runtime nodejs18.x --app-template hello-world-typescript --name ts-test

Adding the default debug config using the toolkit: image

Immediately run debug (f5) results in the issue.

It does seem to be related to where the source map is located. It is looking in the project folder when it should be looking in the toolkit output that is mounted in the docker container Mounting /tmp/aws-toolkit-vscode/vsctku4MLPc/output/HelloWorldFunction as /var/task:ro,delegated, inside runtime container When the container is running I can confirm both app.js and app.js.map are in the container image

shareefer avatar Apr 25 '23 00:04 shareefer

@justinmk3 any update now that I've shared my config?

mattsains avatar May 02 '23 17:05 mattsains

tsconfig.json also plays a role here.

For troubleshooting, try deleting/renaming your tsconfig.json, that will cause AWS Toolkit to generate a temporary tsconfig.json which specifies inlineSourceMap: true: https://github.com/aws/aws-toolkit-vscode/blob/443586906b15d89d951c86b231af275b2651faed/src/shared/sam/debugger/typescriptSamDebug.ts#L173-L180

Alternatively, ensure that inlineSourceMap: true is specified in your tsconfig.json.

Still investigating ways to make this more intuitive.

justinmk3 avatar May 08 '23 18:05 justinmk3

@justinmk3 I tried the workaround you mentioned and the issue still persists unfortunately.

shareefer avatar May 11 '23 16:05 shareefer

This bug just make me give up using typescript to my project.

casyalex avatar Jul 02 '23 10:07 casyalex

You can change tsconfig.json to "noEmit": false, "sourceMap": true, and then run npm run compile. This will generate the missing .js + .map files and then your breakpoint will work. However I agree this should use the map file from the build instead and work out of the box.

ak99372 avatar Sep 19 '23 20:09 ak99372

Any update on this issue? I'm kind of leaning on using JavaScript more and more due to small nuances of TypeScript. Angular projects and other typescript projects simply compile and debug easily but with SAM it's a bit tricky.

ankitbtanna avatar Feb 05 '24 22:02 ankitbtanna

@justinmk3 any update on this will be much appreciated. SAM + Typescript debugging support is fundamental for any meaningful development.

eydelrivero avatar Feb 23 '24 12:02 eydelrivero

@eydelrivero I don't have an update. My previous comments are up to date.

justinmk3 avatar Feb 23 '24 20:02 justinmk3

@justinmk3 Can we get a fix or at least a workimg workaround prioritized? I'm coming from a python background where everything in SAM mostly "just works" and after a week or troubleshooting I still can't get a typescript project with step debugging going.

dangeReis avatar Feb 29 '24 20:02 dangeReis

Which "invokeTarget" is in your launch config? Try using a target=code launch config instead of target=template.

            "invokeTarget": {
                "target": "code",
                ...

justinmk3 avatar Feb 29 '24 23:02 justinmk3

@justinmk3, I'm really new to node, so not really sure how to create the code configuration. I did a whole writeup on how I set up the sam init and step by step what I did to get to my debug configuration, but my browser closed and I lost everything. So I will put my launch.json file here (with 2 configurations, one created from "AWS: Add Debug Configuration" in app.ts and one in template.yaml.

Here is the launch.json.

{
    "configurations": [
        {
            "type": "aws-sam",
            "request": "direct-invoke",
            "name": "hello-world:app.lambdaHandler (nodejs16.x)",
            "invokeTarget": {
                "target": "code",
                "projectRoot": "${workspaceFolder}/hello-world",
                "lambdaHandler": "app.lambdaHandler"
            },
            "lambda": {
                "runtime": "nodejs16.x",
                "payload": {},
                "environmentVariables": {}
            }
        },
        {
            "type": "aws-sam",
            "request": "direct-invoke",
            "name": "sam-app:HelloWorldFunction",
            "invokeTarget": {
                "target": "template",
                "templatePath": "${workspaceFolder}/template.yaml",
                "logicalId": "HelloWorldFunction"
            },
            "lambda": {
                "payload": {},
                "environmentVariables": {}
            }
        }
    ]
}

The template based one executes the code fine, but doesn't hit any breakpoints. The code based one gives me the following error:

Debugger attached.
2024-03-01T01:50:02.455Z	undefined	ERROR	Uncaught Exception 	{"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'app'\nRequire stack:\n- /var/runtime/index.mjs","stack":["Runtime.ImportModuleError: Error: Cannot find module 'app'","Require stack:","- /var/runtime/index.mjs","    at _loadUserApp (file:///var/runtime/index.mjs:1087:17)","    at async Object.load (file:///var/runtime/index.mjs:1119:21)","    at async start (file:///var/runtime/index.mjs:1282:23)","    at async file:///var/runtime/index.mjs:1288:1"]}
Waiting for the debugger to disconnect

I am also attaching the full project archive. For some reason, github doesn't believe in tar.bz2 files so here's a gz one. Got the following error trying to upload .tar.bz2 file

Try again with GIF, JPEG, JPG, MOV, MP4, PNG, SVG, WEBM, CPUPROFILE, CSV, DMP, DOCX, FODG, FODP, FODS, FODT, GZ, JSON, JSONC, LOG, MD, ODF, ODG, ODP, ODS, ODT, PATCH, PDF, PPTX, TGZ, TXT, XLS, XLSX or ZIP.

sam-app.tar.gz

dangeReis avatar Mar 01 '24 01:03 dangeReis

You likely need to build the typescript project before trying to debug. AWS Toolkit doesn't automatically do that, I think.

justinmk3 avatar Mar 01 '24 20:03 justinmk3

It does. I think the issue is with source mappings, because of the temp folder.

Building codeuri: /Users/dangereis/Projects/serverless/sam-app/hello-world runtime: nodejs16.x metadata: {'BuildMethod': 'esbuild', 'BuildProperties': {'Minify': False, 'Target': 'es2020', 'Sourcemap': True, 'EntryPoints': ['app.ts']}} architecture: arm64 functions: HelloWorldFunction
2024-03-01 21:04:19.537 [info] Running NodejsNpmEsbuildBuilder:CopySource
2024-03-01 21:04:19.634 [info] Running NodejsNpmEsbuildBuilder:NpmInstall
2024-03-01 21:04:21.557 [info] Running NodejsNpmEsbuildBuilder:EsbuildBundle
2024-03-01 21:04:21.655 [info] Running NodejsNpmEsbuildBuilder:CleanUp
2024-03-01 21:04:21.656 [info] Running NodejsNpmEsbuildBuilder:MoveDependencies
2024-03-01 21:04:21.794 [info] Sourcemap set without --enable-source-maps, adding --enable-source-maps to function HelloWorldFunction NODE_OPTIONS

The problem is incorrect source maps:

✅ This breakpoint was initially set in:

/Users/dangereis/Projects/serverless/sam-app/hello-world/app.ts line 13 column 1

❓ We couldn't find a corresponding source location, but found some other files with the same name:

/Users/dangereis/Projects/serverless/sam-app/hello-world/private/var/folders/75/__31qtms4cg7cmtysggyt54hwn98c6/T/tmpgo8iz08n/app.ts
If this is the same file, you may need to adjust your build tool to correct the paths.

dangeReis avatar Mar 02 '24 03:03 dangeReis

I think the issue is with source mappings, because of the temp folder.

👍 That may also be the root cause of https://github.com/aws/aws-toolkit-vscode/issues/4470

justinmk3 avatar Mar 04 '24 18:03 justinmk3

I manually changed the .js.map file in ./.aws-sam to use my source .ts file after sam build but it only works intermittently. I need to set a break point at the last line of node_modules/lambda-runtime/dist/node16/index.mjs await start();. Then it seems to have enough time to bind the break points. (I have one at the very first line of the lambda function.)

barryki avatar Jul 23 '24 23:07 barryki

I receive the following error:

Debugger attached.
Could not read source map for file:///var/task/app.js: ENOENT: no such file or directory, open 'd:\Matt\Documents\coding-projects\algoa-gtfs\generate-gtfs\app.js.map'
2023-03-04T19:23:29.832Z	35b556c5-afc6-4038-9b97-ab49edea2f37	INFO	hello world
END RequestId: 35b556c5-afc6-4038-9b97-ab49edea2f37
REPORT RequestId: 35b556c5-afc6-4038-9b97-ab49edea2f37	Init Duration: 0.09 ms	Duration: 105546.28 ms	Billed Duration: 105547 ms	Memory Size: 128 MB	Max Memory Used: 128 MB	
null

To workaround this, add path mappings to the lambda launch configuration in launch.json:

      "lambda": {
        "payload": {},
        "environmentVariables": {},
        "pathMappings": [
          {
            "localRoot": "${workspaceFolder}/.aws-sam/build/HelloWorldFunction",
            "remoteRoot": "/var/task"
          }
        ]
      },

barryki avatar Jul 24 '24 00:07 barryki