Breakpoints in Visual Studio Code not hit when debugging mocha tests - node.js

I'm using Mocha (and Chai) for my unit tests for a NodeJS module and want to debug it in Visual Studio code. I have a TypeScript file in the test subfolder with some tests. VScode generates the .js and .map file in the out dir (via tsc watch mode task). My tsconfig.json file contains these settings:
{
"compilerOptions": {
"compileOnSave": true,
"module": "commonjs",
"target": "es6",
"outDir": "out",
"removeComments": true,
"noImplicitAny": true,
"sourceMap": true,
"inlineSources": true,
"isolatedModules": false,
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true
},
"include": [
"src/**/*", "parser/**/*", "test/**/*"
],
"exclude": [
"node_modules",
".vscode-test"
]
}
and the out dir contains 3 subdirs for the 3 includes. All fine so far.
I can run my tests using this command:
mocha --compilers ts:ts-node/register,tsx:ts-node/register
outside of vscode. Then I ran this code with the --debug-brk switch and attached vscode to it. This works, but no breakpoint is hit. The configuration in launch.json for that is:
{
"name": "Attach",
"type": "node",
"request": "attach",
"port": 5858,
"address": "localhost",
"restart": false,
"sourceMaps": true,
"outDir": null,
"localRoot": "${workspaceRoot}",
"remoteRoot": null
}
Ideally, I'd like to have a run config so that I don't need to run mocha manually. With these settings I can at least run the tests:
{
"name": "Mocha",
"type": "node",
"request": "launch",
"cwd": "${workspaceRoot}",
"preLaunchTask": "tsc",
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
"args": [ "--no-timeouts", "--colors", "${workspaceRoot}/out/test/**/*.js" ],
"stopOnEntry": true,
"runtimeExecutable": null,
"env": {
"NODE_ENV": "testing"
}
"sourceMaps": true
}
but still, no breakpoint is hit.
What is required to make at least one of the 2 scenarios work?
Update: meanwhile I found by accident that breakpoints start working when you add a debugger; command somewhere in the test code and set at least one fresh breakpoint after it stopped on debugger;. After that all following breakpoints in this single file work as expected. Looks almost like a bug to me.

Using "protocol": "inspector", in the launch options helped me to continue for a while, even though this had the annoying side effect that the test process never stopped after everything was executed. I had to kill the task after each run. So I though i'd give it another try to find the problem and I succeeded. The solution is simple: add the outfiles option to your launch options, otherwise vscode will look for maps in the TS source folder. By adding:
"outFiles": [
"${workspaceRoot}/out/**/*.js"
],
everything started to work nicely. It would so helpfull if vscode would print a warning that it cannot find the source maps because of this missing setting.

situtaion
using Jasmine unit test (not Mocha)
when I click the Debug button on a unit test
-> it doesnt stop on the breakpoint, just runs to the end.
solution (in short)
(this may not apply to everyone's case)
it could be the port 9229 is taken by other process on your computer
try debugging in terminal, instead of in Vscode, and see what happens (I tried it in powershell)
eg: node --inspect-brk /usr/local/lib/node_modules/jasmine/bin/jasmine.js ~/exercism/javascript/leap/leap.spec.js
-> then the error shows up: Starting inspector on 127.0.0.1:9229 failed: permission denied (in my case)
find the process that is using the port & close it (lots online discussion on how to do this)
run netstat -ano | findstr 9229
or, you can find it in the Task Manager > Resource Monitor > Network > check your ports
run net stop hns && net start hns to restart your Host Network Service
I found this especially useful when you cannot find the port is taken by which process -- maybe due to that is a dynamic port
after resetting the port -> click the debug button on unit test -> should stop at breakpoint
---
situation & some comments (minor)
some online posts said:_ add the config in launch.json. doesnt help -- the default launch has no problem
the default config uses port 9229
some online posts said:_ use Chrome config to debug. feels unnecessary & its using the browser not nodejs
output panel in vscode Test Explorer shows nothing to indicate the error
this port issue can due to some software that mess around with dynamic port (eg: sometime could be related to some software that change your system proxy / ip).
(this once messed up with my other softwares eg: ActivityWatch)
reference (minor)
[]
"port": 9229,
<>
https://github.com/hbenl/vscode-jasmine-test-adapter
[]
1. run node --inspect-brk node_modules/mocha/bin/mocha test.js:
<>
https://youtrack.jetbrains.com/issue/WEB-43747
[]
I managed to start the debugger by running node --inspect-brk with the jasmine.js file called by Jasmine's CLI:
Kurts-MacBook-Pro:bin kurtpeek$ node --inspect-brk /usr/local/lib/node_modules/jasmine/bin/jasmine.js ~/exercism/javascript/leap/leap.spec.js
<>
How to drop into a debugger in a Jasmine test?
[]
Secondly, check if the port is in the excludedportrange by command "netsh int ipv4 show excludedportrange protocol=tcp".
Then check the dynamicport range by command "netsh int ipv4 show dynamicport tcp".
Set the start of dynamicport by command "netsh int ipv4 set dynamicport tcp start=49152 num=16384"
其次,用命令"netsh int ipv4 show excludedportrange protocol=tcp"检查是否在被排除的端口范围内。
然后用命令"netsh int ipv4 show dynamicport tcp"检查动态端口范围。
用命令"netsh int ipv4 set dynamicport tcp start=49152 num=16384"设置起始动态端口。
<>
https://github.com/eggjs/egg/issues/2432
[]
net stop hns && net start hns
<>
An attempt was made to access a socket in a way forbidden by its access permissions. Why?
[]
The port 9229 is the default debug port of the --inspect and --inspect-brk options.
<>
https://code.visualstudio.com/docs/nodejs/nodejs-debugging

Related

How to debug NextJS during the build phase

My nextJS app have a path with 50k plus pages.
Running with npm run dev it works fine, but during build it gives me an error TypeError: Cannot read property 'page' of undefined at exportPaths.filter.route
That is weird, because I know how many paths I am trying to do (56,427) and they are fine.
I would really like to see where I messed up, but I can't launch a debugger for build stage ending with 'Starting inspector' multiple messages.
I have tried other ways, but with no success.
Here is my config, which is pretty obsolete, but seems straightforward:
{
"type": "node",
"request": "launch",
"name": "Next: Node",
"runtimeExecutable": "${workspaceFolder}/node_modules/next/dist/bin/next",
"env": {
"NODE_OPTIONS": "--inspect"
},
"args": ["build"],
"port": 9229,
"console": "integratedTerminal"
}
P.S. Debugging npm run dev works fine
P.P.S. trying to 'listen' to the debugger in VS Code and launching debugger from command line, like in here https://nextjs.org/docs/advanced-features/debugging gives me the same problems.

VSCode 1.20.1 will not stop at any Node.js v8 breakpoints, what am I doing wrong?

I am trying to get VSCode 1.20.1 to break at a breakpoint in my project, but it simply refuses to break (at least with the inspector protocol). I've distilled this down to a 3 line Node.js sample project which can be found here on GitHub, I'll paste the relevant sections below.
The index.js program is a simple Hello World with a delay to avoid any debugger attach races (more on that later).
setTimeout(() => {
console.log('Hello'); //Breakpoint is set here
}, 5000);
The launch.json is below:
{
// 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": "Normal Run",
"runtimeExecutable": "${workspaceFolder}/bin/node",
"runtimeArgs": [
"--nolazy",
"--inspect-brk=0.0.0.0:5858"
],
"program": "${workspaceFolder}/index.js",
"args": [],
"env": {
"DOCKER_ARGS": "-p5858:5858"
},
"address": "127.0.0.1",
"port": 5858,
"timeout": 60000,
"console": "integratedTerminal",
"smartStep": true,
"stopOnEntry": false,
"protocol": "inspector",
"autoAttachChildProcesses": true,
"localRoot": "${workspaceFolder}",
"remoteRoot": "/src"
}
]
}
Note that Node.js is running in Docker in the standard node:8 container with a volume mount of the local source directory (that is what the runTimeExecutable is for, see GitHub). If I use Wireshark to monitor port 5858, I can see the debugger attach and decode all messages. Strangely, VSCode issues the Runtime.runIfWaitingForDebugger immediately, and then later issues the Debugger.setBreakpointByURL message that seems to be accepted by Node.js (it successfully returns a Location for the breakpoint). I have the 5 second timeout in the code just in case this race is the cause of the problem (which it does not seem to be).
As an aside, if I use my host Node.js (6.11.4) with the protocol as legacy (or auto which chooses legacy) and comment out the runtimeArgs, runtimeExecutable, etc. VSCode hits the breakpoint. If I force the protocol to inspector (which is experimental in 6.11.4) and add back the runtimeArgs (but not executable) the debugger attaches but no breakpoint is hit, essentially the same behavior as with the Docker node:8 above.
What am I doing wrong here? This problem originally started in a new TypeScript project using sourcemaps and mocha, etc. but I've boiled it down to this.

Electron main and renderer process debug configuration

I'm using that repo https://github.com/SimulatedGREG/electron-vue
and trying to set up VS Code debug configurations like this
{ //main
"name": "Attach",
"type": "node",
"request": "attach",
"port": 5858,
"sourceMaps": true
},
{
"name": "Debug Renderer Process",
"type": "chrome",
"request": "attach",
"url": "http://localhost:9080",
"webRoot": "${workspaceRoot}/src"
}
and got messages like
Invalid responce {
"description": "node.js instance",
"devtoolsFrontendUrl": "chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:5858/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e",
"faviconUrl": "https://nodejs.org/static/favicon.ico",
"id": "0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e",
"title": "node",
"type": "node",
"url": "file://",
"webSocketDebuggerUrl": "ws://127.0.0.1:5858/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e"
}
for main and
connect ECONNREFUSED 127.0.0.1:9229
for render processes.
I know that both main and renderer procs are served by webpack 3 and webpack-dev-server 2 but cannot find debug configurations.
Debugging main process using Chrome using link like chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:5858/6c1d575a-d0f6-4ffa-9465-065ebc3d302c works but want to use VS Code.
What am I doing wrong? Can somebody share debug configurations for VS Code or WebStorm?
So this was a real pain to figure out, mainly because the vue electron boilerplate does some in-house management of the main and renderer process. The first challenge is to attach to the child process (main) as reliably as possible. The second challenge is to make sure breakpoints persist across sessions and things like that. This answer doesn't focus on the renderer process at all, because you can just debug that in the devtools console.
Put these two configurations in your launch.json, and add --no-lazy to the dev script in package.json to fix breakpoints. If you're just looking for the solution, you can probably stop reading here. If it didn't work, keep on reading.
{
"type": "node",
"request": "launch",
"name": "Electron: Main (npm)",
"cwd": "${workspaceFolder}",
"outFiles": ["${workspaceFolder}/**/*.js"],
"runtimeExecutable": "npm",
"runtimeArgs": ["run-script", "dev"],
"outputCapture": "std",
"smartStep": true,
"sourceMaps": true,
"protocol": "inspector",
"port": 5858,
"timeout": 20000
},
{
"name": "Electron: Main (attach)",
"type": "node",
"request": "attach",
"cwd": "${workspaceFolder}",
"outFiles": ["${workspaceFolder}/**/*.js"],
"skipFiles": ["init.js"],
"smartStep": true,
"sourceMaps": true,
"protocol": "inspector",
"port": 5858,
"timeout": 20000
}
The first one can be executed with no additional actions needed. It will run the script via npm, and attach directly to the sub process with inspect port 5858.
The second script lets you run npm run dev from a terminal, and then attach. It may be convenient to use this one, if you're more used to it.
Now I will explain why I have used all the settings, in case things change and you're wondering if this is outdated.
"cwd": "${workspaceFolder}",
I could not reliably run the session without doing this. It still worked sometimes though.
"outFiles": ["${workspaceFolder}/**/*.js"],
I could not debug any files without this on.
"outputCapture": "std",
I did not get any output from dev-runner.js if I didn't have this set.
"smartStep": true,
When I restarted the session (especially using the npm variant), the breakpoints got unset and black. This option actually fixed it, but looking an this issue, I suspect you shouldn't normally have to use this option.
"sourceMaps": true,
If you're seeing gibberish code, you may want to add the following:
/**
* Adjust mainConfig for development settings
*/
if (process.env.NODE_ENV !== 'production') {
mainConfig.devtool = 'source-map' // <- THIS
mainConfig.plugins.push(
new webpack.DefinePlugin({
__static: `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`
})
)
}
This option helps with that.
"protocol": "inspector",
Might as well. Legacy doesn't work.
"port": 5858,
This is the port of the child process, spawned by dev-runner.js
"timeout": 20000
Since we're waiting for a child process to finish spawning, it may take longer than 10 seconds to launch and then attach. I set it to 20 seconds, but you are free to lower it if your PC is fast enough. (default is 10s)
Further references in the world of bleeding edge software.
VS Code version: 1.21
Electron version: 1.8.7
Chromium: v59
Node: 8.2.1
you may need to use new inspect protocol in vs code with latest electron binary. It'll looks like
{
"type":"node",
"request":"launch",
"name":"Electron Main",
"runtimeExecutable":"${workspaceRoot}/node_modules/.bin/electron",
"args":[
"${workspaceRoot}/main.js",
"--remote-debugging-port=9333" //Set debugging port for renderer process
],
"protocol":"inspector" //Specify to use v8 inspector protocol
}
important piece is you are specifying protocol to use inspect instead of old node debug. I've wrote summary around this while ago at https://kwonoj.github.io/en/post/multi-target-dbg-electron-vscode/ .

VS Code debug port mismatch

Details
In Win10. VS Code, Help, About...
[Window Title]
Visual Studio Code
[Content]
Version 1.14.2
Commit cb82febafda0c8c199b9201ad274e25d9a76874e
Date 2017-07-19T23:34:09.706Z
Shell 1.6.6
Renderer 56.0.2924.87
Node 7.4.0
Generated launch.json, adjusted with my runtime... settings
{
// Use IntelliSense to learn about possible Node.js debug 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": "Launch Program",
"cwd": "${workspaceRoot}",
"runtimeExecutable": "npm.cmd",
"runtimeArgs": [
"run", "functional-test"
],
"skipFiles": [
"<node_internals>/**/*.js"
]
}
]
}
Npm script referenced above...
"functional-test": "node test/functional/run-foo-tests",
First attempt
I then launch a debug session (F5), which in the Debug Console then yields...
Debugging with inspector protocol because a runtime executable is set.
npm.cmd --inspect=32825 --debug-brk run functional-test
Note the additional flags that aren't specified anywhere in my package.json or launch.json.
In addition to that message above, I am shown a popup in the IDE referencing a connection timeout error...
Cannot connect to runtime process, timeout after 10000 ms - (reason:
Cannot connect to the target: connect ECONNREFUSED
Second attempt
If I change the npm script as follows (include --inspect flag)...
"functional-test": "node --inspect test/functional/run-foo-tests",
The Debug Console states...
Debugging with inspector protocol because a runtime executable is set.
npm.cmd --inspect=17976 --debug-brk run functional-test
Debugger listening on port 9229.
Warning: This is an experimental feature and could change at any time.
Note different port settings. At least the debugger is starting and giving me a port to try and target instead.
Where is it getting those values? How can I make them match (without manually editing both launch.json and npm script to assign the same port for both)?
It never successfully loads and instead I am shown the popup message at the top (mentioned above.)
Third attempt
If I edit the npm script to add the port...
"functional-test": "node --inspect=9229 test/functional/run-foo-tests",
And edit launch.json's port setting to match...
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"cwd": "${workspaceRoot}",
"runtimeExecutable": "npm.cmd",
"runtimeArgs": [
"run", "functional-test"
],
"port": 9229,
"skipFiles": [
"<node_internals>/**/*.js"
]
}
]
I then am rewarded with the following message in the Debug Console...
Debugging with inspector protocol because a runtime executable is set.
npm.cmd run functional-test
Debugger listening on port 5858.
Warning: This is an experimental feature and could change at any time.
{Expected console output...}
It will then work correctly (AFAIK!) Note that now the Debug Console's second line (echoing/logging the command ran) now matches the launch.json runtimeArgs settings (where it did not in the first and second attempts.)
Aside from skull-smashing brute force of trial and error, how was one supposed to figure this out (and surely there must be a better way?)
Fourth attempt
Trying to set the port both for the npm script call (obviously not the same as the node ... call in the npm script) and the port config param and it fails as in the first example.
"runtimeArgs": [
"run", "functional-test", "--inspect=5858"
],
"port": 5858,
Fifth attempt
Of course, as I was writing this, I finally found something like an answer via google...
"scripts": {
"debug": "node --nolazy --debug-brk=5858 myProgram.js"
},
Adjusting my script to match yields (in Debug Console)...
Debugging with inspector protocol because a runtime executable is
set. npm.cmd run functional-test (node:12420)
DeprecationWarning: node --debug is deprecated. Please use node
--inspect instead. Debugger listening on 127.0.0.1:5858
I am also shown a different popup at the top...
Cannot connect to runtime process, timeout after 10000 ms - (reason:
Cannot connect to the target: Parse Error).
Sixth attempt
If I change my script to match the info in the Debug Console...
"functional-test": "node --nolazy --inspect test/functional/run-foo-tests",
Debug Console says...
Debugging with inspector protocol because a runtime executable is set.
npm.cmd run functional-test
Debugger listening on port 9229.
Warning: This is an experimental feature and could change at any time.
And popup is...
Cannot connect to runtime process, timeout after 10000 ms - (reason:
Cannot connect to the target: connect ECONNREFUSED 127.0.0.1

Can I run/debug Heroku Node.js app locally with VSCode?

TL; DR
On Microsoft VSCode v1.6.1, how to:
Properly set runtime executable?
Properly pass Heroku arguments?
Run Heroku Node.js app?
Debug Heroku Node.js app?
Details
I have created a Heroku Node.js application, which is launched using the CLI command:
heroku local web
and successfully starts at port 5000.
I am trying to debug it using Microsoft Visual Studio Code, using the following launch.json configuration:
{
"name": "Launch",
"type": "node",
"request": "launch",
"program": "${workspaceRoot}/app.js",
"stopOnEntry": false,
"args": [],
"cwd": "${workspaceRoot}",
"preLaunchTask": null,
"runtimeExecutable": "/usr/local/bin/heroku",
"runtimeArgs": [
"local web",
],
"env": {
"NODE_ENV": "development"
},
"console": "internalConsole",
"sourceMaps": false,
"outFiles": []
}
But VSCode is automagically passing --debug-brk argument to heroku, causing the error:
/usr/local/bin/heroku --debug-brk=23080 'local web' app.js
! `--debug-brk=23080` is not a heroku command.
! See `heroku help` for a list of available commands.
VSCode also does not find heroku command without its full path (seems like it is not loading PATH environment variable).
Any ideas about how to setup the editor?
The following solution works for me:
1) In your procfile add the parameter --debug to the node process
web: node --debug server.js
By default the debugger listens in the port 5858
2) Once you have the node process running, open VSCode and add the following configuration to your launch.json file
{
"type": "node",
"request": "attach",
"name": "Attach to Process",
"port": 5858
}
3) Finally, click the play button in VSCode with the option "Attach to Process" and it should debug your process.
The following solution worked for me.
In my package.json "scripts", I added:
"debug": "node --inspect-brk server.js"
Then, in launch.json I added an envFile entry to the default "Launch via NPM" configuration, which now looks looks like this:
{
"type": "node",
"request": "launch",
"name": "Launch via NPM",
"runtimeExecutable": "npm",
"runtimeArgs": [
"run-script",
"debug"
],
"port": 9229,
"envFile": "${workspaceFolder}/.env"
}
The above solution enables the VSCode debugger to run my server via an npm script, and my server runs with the env vars set in my .gitignore'd .env file, just like in the "regular" Heroku node.js workflow.
I struggled with this as for some reason the solution propsed didn't work for me. However, an alternate solution did so I thought I would share.
From the default debugging options in VS Code choose
Attach by Process ID
When you start the debugger with this configuration it should list available processes to attach to and one should be simply be server.js. This requires manually attaching each time, and if the other automatic attachment works for you that may be better, but this is still a workable solution.

Resources