How to debug relay-starter-kit ? (database.js, schema.js) - node.js

The relay-starter-kit uses babel-node to run the ES6 style JavaScript.
I would like to debug the server side code like database.js and schema.js.
I tried node.js remote debugging but wasn't able to stop in any of my break-points. I also tried different ways of enabling debugging like babel-node --debug ./server.js. But nothing worked so far. I guess somehow I have to tell babel to generate debuggable output with source-maps or so?
To be more exact, how can I debug getUser in database.js for example?
Thank you

Insert a debugger statement
mutateAndGetPayload: ({id, text}) => {
debugger;
/* ... */
},
Run the server with the debugger engaged
$ ./node_modules/.bin/babel-node debug ./server.js
< Debugger listening on port 5858
debug> . ok
break in node_modules/babel/lib/_babel-node.js:1
> 1 "use strict";
2
3 // istanbul ignore next
debug> c
< GraphQL Server is now running on http://localhost:8080
< Relay TodoMVC is now running on http://localhost:3000
break in data/schema.js:278
276 var text = _ref11.text;
277
>278 debugger;
279 var localTodoId = (0, _graphqlRelay.fromGlobalId)(id).id;
280 (0, _database.renameTodo)(localTodoId, text);
debug>

Related

ExpressJS Node Process won't end "normally"

NodeJS v 16.15.1 Windows 10.
Since a few days, neither nodemon nor VSCode can end node processes which use app.listen() of express. When the code changes we see:
[nodemon] restarting due to changes...
But nothing happens after that. We have to kill the processes manually in task manager.
'use strict';
const express = require('express');
const app = express();
const PORT = 8040;
// The PROBLEMATIC line:
app.listen(PORT, () => {
console.log(`Started on http://localhost:${PORT} (PID: ${process.pid})`);
});
If I remove "The PROBLEMATIC line" then nodemon/vscode can restart the process.
There is NO error message, the app just does not exit. For example by entering rs:
Nothing happens, no matter how long I wait.
Using nodemon --signal SIGTERM makes no difference, the process never sees the SIGTERM.
Using the package why-is-node-running we see:
There are 5 handle(s) keeping the process running
# TCPSERVERWRAP
C:\services\overview\node_modules\express\lib\application.js:635 - return server.listen.apply(server, arguments);
C:\services\overview\src\tmp2.js:6 - app.listen(PORT, () => {
# TTYWRAP
C:\services\overview\src\tmp2.js:7 - console.log(`Started on http://localhost:${PORT} (PID: ${process.pid})`);
# HTTPINCOMINGMESSAGE
(unknown stack trace)
# HTTPINCOMINGMESSAGE
(unknown stack trace)
# TickObject
(unknown stack trace)
You want end the node/nodemon process? Why not using ctrl + c instead

advantage of creating node server in background

Until today in all my node\express projects, I have created the HTTP server in some file
var server = http.createServer(app);
http.globalAgent.maxSockets = maxSockets;
server.listen(port, function() {
logger.info('App starting on : ' + port );
});
and called that file directly to start the app. Recently i am noticing some boilerplates, using the approach of calling a starter file and based on arguments, spawn a child process, be it building the app or starting the app
in package json
"start": "babel-node tools/run.js"
in run .js
// Launch `node build/server.js` on a background thread
function spawnServer() {
return cp.spawn(
'node',
[
// Pre-load application dependencies to improve "hot reload" restart time
...Object.keys(pkg.dependencies).reduce(
(requires, val) => requires.concat(['--require', val]),
[],
),
// If the parent Node.js process is running in debug (inspect) mode,
// launch a debugger for Express.js app on the next port
...process.execArgv.map(arg => {
if (arg.startsWith('--inspect')) {
const match = arg.match(/^--inspect=(\S+:|)(\d+)$/);
if (match) debugPort = Number(match[2]) + 1;
return `--inspect=${match ? match[1] : '0.0.0.0:'}${debugPort}`;
}
return arg;
}),
'--no-lazy',
// Enable "hot reload", it only works when debugger is off
...(isDebug
? ['./server.js']
: [
'--eval',
'process.stdin.on("data", data => { if (data.toString() === "load") require("./server.js"); });',
]),
],
{ cwd: './build', stdio: ['pipe', 'inherit', 'inherit'], timeout: 3000 },
);
}
eg : https://github.com/kriasoft/nodejs-api-starter/
how is this advantageous?
In my experience this is not a widespread practice. It appears based on the comments that they're doing it in order to be able to do configuration on command line options based on the environment and so on. To be honest, this seems a bit counterproductive to me.
What I've seen far more often is to start node from the command line with just npm start. package.json has several options for defining what that will do, but most often I would just have it call something simple like node server.js or similar. If you have multiple options for starting that you want to offer (for example, turning on the debug flags and such), then just add more scripts and call npm run <scriptname> to make it happen.
Any other special sauce would be baked into the process manager of choice (systemd is my preference but others like pm2 exist and work well), and between that and the environment variables you can do all or most of what's in the above script without all the indirection. I feel like the example you posted would really up the 'wtf-factor' if I were starting to maintain the app and didn't know that at it was doing things like that for me under the hood.

debugging protactor (with / without webstorm)

So I'm starting out with protractor, and I want to debug my test code:
describe('stuff', function(){
it('should find the specs item, and its empty', function(){
browser.debugger();
gotoHome();
var allItems = element.all('li in model.tags');
var specsDashboardElement;
for (var i=0 ; i < allItems.length; ++i) {
var elem = allItems[i];
var text = elem.findElement(by.css('.li-title').getText()); // does this even work?? dunno
if (text == "Specs")
specsDashboardElement = elem;
}
expect(specsDashboardElement.isDisplayed()).toBe(true);
});
});
I've followed these instructions, but this is the output I see on the node.js debugger console:
D:\src\apps\j1-test.module>protractor debug conf.js
< debugger listening on port 5858
connecting... ok
break in C:\Users\j\AppData\Roaming\npm\node_modules\protractor\lib\cli.js:7
5 * Values from command line options override values from the config.
6 */
7 'use strict';
8
9 // Coffee is required here to enable config files written in coffee-script.
debug> cont
< ------------------------------------
< PID: 9756 (capability: chrome #1)
< ------------------------------------
< debugger listening on port 5858
debug>
and that's it. no matter how many types I type 'cont', nothing happens.
I've tried following the instructions for debugging in WebStorm, with much the same result (output on the WebStorm debug console:
"C:\Program Files\nodejs\node.exe" --debug-brk=2259 C:\Users\j\AppData\Roaming\npm\node_modules\protractor\lib\cli.js
conf.js
debugger listening on port 2259
PID: 2708 (capability: chrome #1)
debugger listening on port 2259
).
I'm using node 0.10.26 (64 bit) on windows 8
Ideas anyone?
That was a Protractor issue, which should be fixed now:
"Fix is in - should be out next release. Thanks for your patience, everyone." - #juliemr
from GitHub issue #552
EDIT: Released in 0.20.0 version! (0.20.1 for Windows users). See Protractor changelog.

How to debug Node.JS child forked process?

I'm trying to debug the child Node.JS process created using:
var child = require('child_process');
child .fork(__dirname + '/task.js');
The problem is that when running in IntelliJ/WebStorm both parent and child process start on the same port.
debugger listening on port 40893
debugger listening on port 40893
So it only debugs the parent process.
Is there any way to set IntelliJ to debug the child process or force it to start on a different port so I can connect it in Remote debug?
Yes. You have to spawn your process in a new port. There is a workaround to debug with clusters, in the same way you can do:
Start your app with the --debug command and then:
var child = require('child_process');
var debug = typeof v8debug === 'object';
if (debug) {
//Set an unused port number.
process.execArgv.push('--debug=' + (40894));
}
child.fork(__dirname + '/task.js');
debugger listening on port 40894
It is a known bug in node.js that has been recently fixed (although not backported to v0.10).
See this issue for more details: https://github.com/joyent/node/issues/5318
There is a workaround where you alter the command-line for each worker process, although the API was not meant to be used this way (the workaround might stop working in the future). Here is the source code from the github issue:
var cluster = require('cluster');
var http = require('http');
if (cluster.isMaster) {
var debug = process.execArgv.indexOf('--debug') !== -1;
cluster.setupMaster({
execArgv: process.execArgv.filter(function(s) { return s !== '--debug' })
});
for (var i = 0; i < 2; ++i) {
if (debug) cluster.settings.execArgv.push('--debug=' + (5859 + i));
cluster.fork();
if (debug) cluster.settings.execArgv.pop();
}
}
else {
var server = http.createServer(function(req, res) {
res.end('OK');
});
server.listen(8000);
}
Quick simple fix ( where using chrome://inspect/#devices )
var child = require('child_process');
child.fork(__dirname + '/task.js',[],{execArgv:['--inspect-brk']});
Then run your app without any --inspect-brk and the main process won't debug but the forked process will and no conflicts.
To stop a fork conflicting when debugging the main process ;
child.fork(__dirname + '/task.js',[],{execArgv:['--inspect=xxxx']});
where xxxx is some port not being used for debugging the main process. Though I haven't managed to easily connect to both at the same time in the debugger even though it reports as listening.
I find that setting the 'execArgv' attribute in the fork func will work:
const child = fork('start.js', [], {
cwd: startPath,
silent: true,
execArgv: ['--inspect=10245'] });
if "process.execArgv" doenst work you have to try:
if (debug) {
process.argv.push('--debug=' + (40894));
}
this worked for me..
There are one more modern way to debug child (or any) process with Chrome DevTools.
Start your app with arg
--inspect
like below:
node --debug=9200 --inspect app/main.js
You will see the message with URL for each child process:
Debugger listening on port 9200.
Warning: This is an experimental feature and could change at any time.
To start debugging, open the following URL in Chrome:
chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9200/207f2ab6-5700-4fc5-b6d3-c49a4b34a311
Debugger listening on port 9201.
Warning: This is an experimental feature and could change at any time.
To start debugging, open the following URL in Chrome:
chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9201/97be3351-2ea1-4541-b744-e720188bacfa
Debugger listening on port 9202.
Warning: This is an experimental feature and could change at any time.
To start debugging, open the following URL in Chrome:
chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9202/8eb8384a-7167-40e9-911a-5a8b902bb8c9
If you want to debug the remote processes, just change the address 127.0.0.1 to your own.

Dynamic arguments for ZINTERSTORE with node_redis

I'm trying to use the ZINTERSTORE command of redis from node.js using node_redis:
//node.js server code
var redis = require("redis");
var client = redis.createClient();
// ... omitted code ...
exports.searchImages = function(tags, page, callback){
//tags = ["red", "round"]
client.ZINTERSTORE("tmp", tags.length, tags.join(' '), function(err, replies){
//do something
});
}
But the call client.ZINTERSTORE throws the error: [Error: ERR syntax error]. Passing in tags as an array (instead of using tags.join(' ')) throws the same error.
Where can I find the correct syntax for this command? The source code for node_redis has it buried in the javascript parser, but it's tricky to see what's going on without 'stepping through' the code. Is there a good way to do step through debugging with node.js?
There are multiple ways to debug a Redis client with node.js.
First you can rely on the Redis monitor feature to log every commands received by the Redis server:
> src/redis-cli monitor
OK
1371134499.182304 [0 172.16.222.72:51510] "info"
1371134499.185190 [0 172.16.222.72:51510] "zinterstore" "tmp" "2" "red,round"
You can see the zinterstore command received by Redis is ill-formed.
Then, you can activate the debugging mode of node_redis by adding the following line in your script:
redis.debug_mode = true;
It will output the Redis protocol at runtime:
Sending offline command: zinterstore
send ncegcolnx243:6379 id 1: *4
$11
zinterstore
$3
tmp
$1
2
$9
red,round
send_command buffered_writes: 0 should_buffer: false
net read ncegcolnx243:6379 id 1: -ERR syntax error
Then, you can use node.js debugger. Put a debugger breakpoint in the code in the following way:
function search(tags, page, callback) {
debugger; // breakpoint is here
client.ZINTERSTORE("tmp", tags.length, tags, function(err, replies){
console.log(err);
console.log(replies);
callback('ok')
});
}
You can then launch the script with node in debug mode:
$ node debug test.js
< debugger listening on port 5858
connecting... ok
break in D:\Data\NodeTest\test.js:1
1 var redis = require("redis");
2 var client = redis.createClient( 6379, "ncegcolnx243" );
3
debug> help
Commands: run (r), cont (c), next (n), step (s), out (o), backtrace (bt), setBreakpoint (sb), clearBreakpoint (cb),
watch, unwatch, watchers, repl, restart, kill, list, scripts, breakOnException, breakpoints, version
debug> cont
break in D:\Data\NodeTest\test.js:8
6 function search(tags, page, callback) {
7
8 debugger;
9 client.ZINTERSTORE("tmp", tags.length, tags, function(err, replies){
10 console.log(err);
... use n(ext) and s(tep) commands ...
By stepping through the code, you will realize that the command array is not correct because the tags are serialized and processed as a unique parameter.
Changing the code as follows will fix the problem:
var cmd = [ "tmp", tags.length ];
client.zinterstore( cmd.concat(tags), function(err, replies) {
...
});

Resources