Why is process.debugPort defined when not debugging? - node.js

I've been exploring the various ways to detect whether a node process has a debugger attached or not. I came across the straightforward looking process.debugPort, which is documented as:
process.debugPort
Added in: v0.7.2
<number>
The port used by the Node.js debugger when enabled.
What do the docs mean by "when enabled"? Or perhaps more to the point, when is the debugger not enabled? A simple test program shows that the process.debugPort always seems to be defined.
'use strict'
const debugPort = process.debugPort
console.log(`debugPort: ${debugPort}`)
Here is some command line output showing its invocation in node v10.22.1 – I tested node v15.3.0 and observed the same behavior.
➜ node --version
v10.22.1
➜ node nodeDebug.js
debugPort: 9229
➜ node --inspect=0.0.0.0:9999 nodeDebug.js
Debugger listening on ws://0.0.0.0:9999/db5cdb75-4745-4ea1-9a87-3f81c811c563
For help, see: https://nodejs.org/en/docs/inspector
debugPort: 9999
So even when invoking node without a --inspect flag, the debugPort is defined (and set to the default of 9229).
As an aside, the best method I've discovered for detecting whether node is in debugging mode or not is inspector.url() which
Return the URL of the active inspector, or undefined if there is none.
I'm not sure if this is bulletproof, but it covers my use case.

Even when you start without the explicit --inspect flag, it's always possible to enable the inspector on an ad hoc basis by sending the process a SIGUSR1 signal like so:
kill -SIGUSR1 $myNodePID
As such, it makes sense that the debugPort property is always set to something, as it's possible that it might be shortly used.
See towards top of here for passing sentence confirming this.

Related

How to get expandable objects view as output in VS Code node terminal?

I would like to have collapsible/ expandable objects in the terminal output in VS Code like on the browser console.
Here is an example:
In the debug terminal it works only if I toggle a breakpoint before the end of the program, but otherwise I get the error "No debugger available, can not send 'variables'".
So I'm thinking if the functionality is there, there must be a way to get it even without setting breakpoints every time. Right?
Use console.dir() instead of console.log().
Use this following example, to display all nested objects:
console.dir(yourStuff, { depth: null })
use
"outputCapture": "std"
in launch.json

How can I stop being blocked by debugger statements in Jest?

I'm just beginning to use Jest in my nodejs project. I have several test and all pass, but the last test I just coded is passing but is blocked in two places by Jest with code like this:
/* istanbul ignore next */
cov_19rdmie87d().s[43]++;
debugger;
/* istanbul ignore next */
cov_19rdmie87d().s[53]++;
this debugger;
I have to hit f5 to continue twice while running my tests. How can I remove these debugging statements?
Solution:
Remove debugger statements from your code and any kind of breakpoints from your inspect sources.
Some more Wiki on Debugging in JS
Debugger : If you place a debugger; line in your code, Chrome will automatically stop there when executing. You can even wrap it in conditionals, so it only runs when you need it.
Type debug(item.myFunc) in the console and the script will stop in debug mode when it gets a function call to item.myFunc
When you need to debug JavaScript, Chrome lets you pause when a DOM element changes. You can even monitor its attributes. In Chrome Inspector, right-click on the element and pick a break on setting to use.
For more information, check out this article by raygun on debugging in javascript.

ignore debugger; statements in Node.js, during debug session

I have a codebase where I have quite a number of
debugger;
statements. Sometimes I debug, and I actually just want to skip all of the debugger; statements and continue only to the manually set breakpoints that I have chosen for the debugging session, is there some setting by chance with Node.js to do that?
In other words, I would like to consider the debugger; statements to be long-term placeholders, but for certain debugging sessions I would like to ignore those long-term placeholders.
That can be done with the chrome devtools.
You can do:
node --inspect --debug-brk index.js
that will generate something like this:
chrome-devtools://devtools/remote/serve_file/#60cd6e859b9f557d2312f5bf532f6aec5f284980/inspector.html?experiments=true&v8only=true&ws=localhost:9229/9c2e4f37-4c3a-4477-b8da-2399c5d9819e
Just copy and paste that on chrome.
There is an option to disable/enable all the break points, and chrome will remember all the breakpoints that you set previously.
Please check: --inspect for more info.
A trick I've used in the past is to just use babel to strip out debugger statements:
See:
https://www.npmjs.com/package/babel-plugin-remove-debugger
Quick and dirty way (its for debug so, its fine really) is to stick something like the following script in scripts/debugger.js
require.extensions['.js'] = function(module, filename) {
var content = fs.readFileSync(filename, 'utf8').replace(/debugger/g, [
'(function() {',
' if (__debugger) {',
' debugger;',
' }',
'})',
].join('\n'));
module._compile(content, filename);
};
then start node with node -r ./scripts/debugger
Using a global variable here so that it can be enabled/disabled from the debugger repl or chrome's repl if debugging with --inspect.
Technically require.extensions is deprecated, but it's not going to be removed and it works as intended here.

node tty ReadStream _handle is null

I am trying to write an Electron launcher for the test runner testem. Testem prints to the terminal the test results from each of it's launchers (forked processes where tests get executed, traditionally browsers but in this case Electron). Testem wants to set the tty to 'Raw Mode' so it can make a faux-tabbed view that appears to update live, and lets the user navigate between tabs to see results from different launchers.
I'm seeing this error in my terminal after testem tries to call process.stdin.setRawMode (on node v4.0.0 on OS X Yosimite):
TypeError: Cannot read property 'setRawMode' of null
at ReadStream.setRawMode (tty.js:49:15)
at module.exports.View.extend.setRawMode (/Users/beane/Code/yeti-desktop/node_modules/testem/lib/dev/ui/appview.js:255:21)
at module.exports.View.extend.cleanup (/Users/beane/Code/yeti-desktop/node_modules/testem/lib/dev/ui/appview.js:265:10)
at EventEmitter.App.cleanupView (/Users/beane/Code/yeti-desktop/node_modules/testem/lib/dev/index.js:254:15)
at /Users/beane/Code/yeti-desktop/node_modules/testem/lib/dev/index.js:230:14
at /Users/beane/Code/yeti-desktop/node_modules/testem/lib/dev/index.js:325:23
at Object.HookRunner.run (/Users/beane/Code/yeti-desktop/node_modules/testem/lib/hook_runner.js:13:14)
at EventEmitter.App.runHook (/Users/beane/Code/yeti-desktop/node_modules/testem/lib/dev/index.js:322:12)
at EventEmitter.App.runExitHook (/Users/beane/Code/yeti-desktop/node_modules/testem/lib/dev/index.js:312:10)
at /Users/beane/Code/yeti-desktop/node_modules/testem/lib/dev/index.js:229:12
at /Users/beane/Code/yeti-desktop/node_modules/testem/node_modules/async/lib/async.js:52:16
at Object.async.forEachOf.async.eachOf (/Users/beane/Code/yeti-desktop/node_modules/testem/node_modules/async/lib/async.js:236:30)
at Object.async.forEach.async.each (/Users/beane/Code/yeti-desktop/node_modules/testem/node_modules/async/lib/async.js:209:22)
at EventEmitter.App.cleanUpLaunchers (/Users/beane/Code/yeti-desktop/node_modules/testem/lib/dev/index.js:365:11)
at EventEmitter.App.quit (/Users/beane/Code/yeti-desktop/node_modules/testem/lib/dev/index.js:228:10)
at process.App.quiteGracefully (/Users/beane/Code/yeti-desktop/node_modules/testem/lib/dev/index.js:43:10)
The stacktrace begins at tty.js:49 from node core. Here's the function where the error is thrown from:
ReadStream.prototype.setRawMode = function(flag) {
flag = !!flag;
this._handle.setRawMode(flag);
this.isRaw = flag;
};
What I can't seem to figure out is what the heck this._handle is. Testem is not expecting it to be null, but for some reason it is. Can anyone help me out with this?

Nodejs Debugger misses out some property names on autocompletion in repl mode

var express = require('express');
Debugger;
var router = express.Router();
In node debugger, when the control stops at second line, i do this,
debug> repl
Press Ctrl + C to leave debug repl
> express
[Function]
> express.
here, after 'express.', pressing tab for autocomplete doesn't list out Router option but node builtin properties like hasOwnProperty, call, bind... are there.
express.Router
is defined in
`node_modules/express/lib/router/index.js`.
I see, no reason this property may not be part of the express object.
In summary, node debugger autocompletion is not listing all the properties for express object.
This is a side-effect of the fact that express exports a function rather than a standard object. e.g.
module.exports = function(){ ...}
module.exports.Router = Router;
It all comes down to this line in the Node source, which ends up basically saying "if autocompleting a function, treat it like a simple anonymous function", thus it doesn't have any extra properties.
The reason for the roundabout code is because when you run node debug ..., you are actually starting two node processes, with one running your code, and one running the debugger. That means that when you autocomplete, the debugger process must send a message to the process being debugged, asking for information, and then it has to translate that back into something that you can render for autocompletion.
Looking over the node core source, my educated guess would be that this was simply the easiest thing to do. The current architecture of the debugger tries to hide the debugger implementation as much as possible, but that means that the autocompleter doesn't know that it is working on a faked object copy and the debugger doesn't know that we are autocompleting. The downside of this is that it tries to recursively duplicate the whole object before processing the autocomplete, meaning it does a costly recursive operation to then simply discard the result. Unfortunately adding function property recursion makes the autocomplete quite slow from my quick test a minute ago.

Resources