Why the root of my stack in node.js + node-inspector is not the real root, I mean a function ran from an outrside source (like driver) - node.js

I have a a debugger point in my code and I look in the call stack, I see about 11 lines deep but I cannot dig more. In the last level, the deeper one, is not a response from an async call like a driver nor an entry program, it's just some function called by another. But I cannot see that another function...
Any help how to see the other function?
thanks

You could try out https://github.com/CrabDude/trycatch and wrap some of your initial code with it.
var trycatch = require('trycatch')
trycatch(yourOriginalFunction, exceptionHandlerCallback)
It should give you a long stacktrace with your original function in it.
There are other libraries trying to solving this problem too but I haven't used them:
https://github.com/tlrobinson/long-stack-traces
https://github.com/mattinsler/longjohn

Related

How to read nodejs documentation regarding callback parameters (node v8.x)

I am trying to understand the node.js documentation specifically for the https.get() method. https://nodejs.org/dist/latest-v8.x/docs/api/https.html#https_https_get_options_callback
What is unclear to me is the callback. The example in the document indicates the callback can take a res (response) object as its parameter but I am unsure if this is the only parameter it can take or more importantly where I can find the definition of the res object so I can know what properties and methods I can access on this object.
Is there a straightforward way to identify this?
I have read this thread: Trying to understand nodejs documentation. How to discover callback parameters and the answers seem to suggest that if there is a non-error argument that a callback can take it will be documented, but I am assuming that answer is outdated.
I've run into the same issue with many Node/NPM packages. Documentation sometimes does not describe the parameters well.
So, welcome to JavaScript in 2018! It's gotten a lot better, though, to be honest.
My go-to method is to try the methods and dump the information myself.
Try a console.dir(res) in your callback:
https.get('https://encrypted.google.com/', (res) => {
console.dir(res);
});
Alternatively, you can set a breakpoint in the callback and inspect it yourself. You can then probe the arguments object* to see what else, if anything, was passed as an argument, or do another console dump:
https.get('https://encrypted.google.com/', function (res) {
console.dir("args:", arguments);
console.dir("res:", res);
});
EDIT: Wait, apparently the arguments variable is not available to arrow functions, fixed the second example.
*From MDN:
The arguments object is not an Array. It is similar to an Array, but
does not have any Array properties except length.
From your link https://nodejs.org/dist/latest-v8.x/docs/api/https.html#https_https_get_options_callback, you can see that it works like the http version :
Like http.get() but for HTTPS.
With http.get() clickable.
On that page (https://nodejs.org/dist/latest-v8.x/docs/api/http.html#http_http_get_options_callback), we can see this :
The callback is invoked with a single argument that is an instance of http.IncomingMessage
With http.IncomingMessage clickable, linking this page :
https://nodejs.org/dist/latest-v8.x/docs/api/http.html#http_class_http_incomingmessage
I agree the Node documentation is not very clear about the callbacks in general, and that is a shame. You can still use IDEs with good intellisense (and JSDoc to identify the type of the function parameters), like VSCode.
Or you can use a debugger, always works :)
Edit: If you want to see all the parameters sent to a function, you can use the spread syntax like this :
function foo(...params) {
// Here params is an array containing all the parameters that were sent to the function
}
If you want the absolute truth, you can look at the implementation. Though that's fairly time consuming.
If you find that the documentation is wrong, or in this case could be improved by adding a sentence about the callback parameter to https.get(), please open an issue, or, better yet, a pull request. This is where the change needs to be made:
https://github.com/nodejs/node/blob/67790962daccb5ff19c977119d7231cbe175c206/doc/api/https.md

Node - console.log + return values

I'm just getting started in programming and am using VSC and installed Node and am using it to run my files. My console.logs works, but I can't get return values when I invoke functions. What am I doing wrong?
Node.js is asynchronous. 99% of all functions you write are going to be "non-blocking". If you don't quite understand what that is, I highly suggest you google up on the node.js event loop, and what it means to be "asynchronous".
Once you figure that out, start using the async/await syntax, or "promise" syntax.
Edit:
I see you posted more information. Based on what you're doing, it actually has nothing to do with being asynchronous.
The problem is that you're just returning a string value of hihihihihi... and that's it. You don't print it out anywhere. You need to wrap your call to function a() inside console.log(). So like: console.log(a());

webdriver-sync running asynchronously?

I'm trying to create selenium tests that run each step synchronously, without using .then(), or async/await. The reason for this is that I want to create a set of functions that allow pretty much anyone on our test team, almost regardless of tech skills to write easy to read automated tests. It looks to me like webdriver-sync should give me exactly what I want. However, the following dummy code is producing problems:
var wd = require('webdriver-sync');
var By = wd.By;
var Chromedriver = wd.Chromedriver;
var driver = new Chromedriver;
driver.get('https://my.test.url');
var myButton = driver.findElement(By.cssSelector('[id*=CLICK_ME]'));
myButton.click();
It tries to run - browser is launched, and page starts to load... but the steps are not executed synchronously - it goes on and tries to find and click "myButton" before the page has finished loading, throwing a "no such element" error... which to me kinda defeats the point of webdriver-sync?! Can someone tell me where I am going wrong?
FWIW, I have webdriver-sync 1.0.0, node v7.10.0, java 1.8.0_74, all running on CentOS 7.
Thanks in advance!
You need to put double-quotes around "CLICK_ME" as it's a string value.
Generally, though, it's a good idea to Wait for specific elements because dynamic pages are often "ready" before all their elements have been created.

Interacting with app code in the node REPL

One of the pleasures of frameworks like Rails is being able to interact with models on the command line. Being very new to node.js, I often find myself pasting chunks of app code into the REPL to play with objects. It's dirty.
Is there a magic bullet that more experienced node developers use to get access to their app specific stuff from within the node prompt? Would a solution be to package up the whole app, or parts of the app, into modules to be require()d? I'm still living in one-big-ol'-file land, so pulling everything out is, while inevitable, a little daunting.
Thanks in advance for any helpful hints you can offer!
One-big-ol'-file land is actually a good place to be in for what you want to do. Nodejs can also require it's REPL in the code itself, which will save you copy and pasting.
Here is a simple example from one of my projects. Near the top of your file do something similar to this:
function _cb() {
console.log(arguments)
}
var repl = require("repl");
var context = repl.start("$ ").context;
context.cb = _cb;
Now just add to the context throughout your code. The _cb is a dummy callback to play with function calls that require one (and see what they'll return).
Seems like the REPL API has changed quite a bit, this code works for me:
var replServer = repl.start({
prompt: "node > ",
input: process.stdin,
output: process.stdout,
useGlobal: true
});
replServer.on('exit', function() {
console.log("REPL DONE");
});
You can also take a look at this answer https://stackoverflow.com/a/27536499/1936097. This code will automatically load a REPL if the file is run directly from node AND add all your declared methods and variables to the context automatically.

node.js fibers with pg/postgres

I've been trying to figure out how to use node-fibers to make my database code less messy in node.js, but I can't get it to work. I boiled the code down to this as a minimum test case:
var Future = require('fibers/future');
var pg=require('pg');
var connstr = "pg://not_the_real_user:or_password#localhost/db";
var pconnect = Future.wrap(pg.connect);
Fiber(function() {
var client = pconnect(connstr).wait();
console.log("called function");
}).run();
If I leave it as is, I get the following error:
pgfuture.js:10
}).run();
^
TypeError: undefined is not a function
at Object.PG.connect.pools.(anonymous function).genericPool.Pool.create (/home/erik/code/treehouse-node/node_modules/pg/lib/index.js:49:20)
at dispense (/home/erik/code/treehouse-node/node_modules/pg/node_modules/generic-pool/lib/generic-pool.js:223:17)
at Object.exports.Pool.me.acquire (/home/erik/code/treehouse-node/node_modules/pg/node_modules/generic-pool/lib/generic-pool.js:267:5)
at PG.connect (/home/erik/code/treehouse-node/node_modules/pg/lib/index.js:75:15)
at Future.wrap (/home/erik/code/treehouse-node/node_modules/fibers/future.js:30:6)
at /home/erik/code/treehouse-node/pgfuture.js:8:18
However, if I comment out the line that calls pconnect, I get the "called function" message on the console and no errors. The example on the github page has an almost identical structure, and it does work correctly on my system, but I'm stumped as to what I'm doing wrong here.
Edit: Additional details
I've managed to get the code to run after a fashion in two different ways that seem unrelated, but both have the same behavior. After the function finishes, node just hangs and I have to kill it with ctrl-c. Here are the two things I've done to get that result:
1) Wrap pg.connect in an anonymous function, and then wrap THAT with Future:
pconnect = Future.wrap(function(err,cb){pg.connect(err,cb);});
2) This one is a real mystery, but it appears to have the same result. Inside the fiber, I just directly call pg.connect before the call to pconnect, and everything seems to work out.
// add this line before call to pconnect
pg.connect(connstr, function(e,c){console.log("connected.");});
// and now the original call to pconnect
var client = pconnect(connstr).wait();
I can imagine a circumstance in which (1) would make sense if, for example, the pg.connect function has other optional arguments that are somehow interfering with the expected layout of the Future.wrap call. Another possibility is that an object is going out of scope and the "this" reference is undefined when the actual call to pconnect is made. I'm at a loss to understand why (2) has any effect though.
Edit: partial answer
Okay, so I answered at least part of the question. The thought I had about object scope turned out to be correct, and by using the bind() function I was able to eliminate the extra layer of callback wrapping:
var pconnect = Future.wrap(pg.connect.bind(pg));
It still hangs at the end of the execution for unknown reasons though.
Are you disconnecting from database at the end of execution?
If not, it prevents node.js program from exiting.
Adding another code of my own which leaks.
#Almad I'm disconnecting here with the provided callback, but still hangs:
var future = Future.task(function() {
var ret = Future.wrap (pg.connect.bind(pg), "array") (conString).wait ();
ret[1]();
}).detach();

Resources