aws / aws-toolkit-vscode

Amazon Q, CodeCatalyst, Local Lambda debug, SAM/CFN syntax, ECS Terminal, AWS resources
https://marketplace.visualstudio.com/items?itemName=AmazonWebServices.amazon-q-vscode
Apache License 2.0
1.49k stars 417 forks source link

SAM: debug typescript lambda locally #3210

Open mattsains opened 1 year ago

mattsains commented 1 year ago

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

ffMathy commented 1 year ago

We have this issue too.

justinmk3 commented 1 year ago

Can you share the launch config you are using?

Related:

mattsains commented 1 year ago

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

shareefer commented 1 year ago

+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
mattsains commented 1 year ago

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

justinmk3 commented 1 year ago

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.

shareefer commented 1 year ago

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

casyalex commented 1 year ago

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

ak99372 commented 1 year ago

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.

ankitbtanna commented 7 months ago

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.

eydelrivero commented 7 months ago

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

justinmk3 commented 7 months ago

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

dangeReis commented 7 months ago

@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.

justinmk3 commented 7 months ago

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

            "invokeTarget": {
                "target": "code",
                ...
dangeReis commented 7 months ago

@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

justinmk3 commented 7 months ago

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

dangeReis commented 7 months ago

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.
justinmk3 commented 7 months ago

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

barryki commented 2 months ago

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 commented 2 months ago

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"
          }
        ]
      },