node tty ReadStream _handle is null - node.js

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?

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

Weird node.js console.log() output behaviour when printing arrays

I have the following, somewhat simple code in VSCode(Mac OS) which I run in node.js v14.13.1 environment:
let fruits = ['Apple', 'Banana'];
let fruits1 = ['Apple1', 'Banana1'];
console.log(fruits);
console.log(fruits1);
The output behaviour seems very weird to me, it prints either:
(2) ['Apple', 'Banana']
or
(2) ['Apple', 'Banana']
(2) ['Apple1', 'Banana1']
or
(2) ['Apple', 'Banana']
Canceled
I couldn't find any particular pattern of printing (except for first two outputs are printed more often than the third one), so it seems as if it 'randomly decides' what to output.
This code, however, outputs always as expected when executed via Mac terminal(node my_file.js), i.e.:
[ 'Apple', 'Banana' ]
[ 'Apple1', 'Banana1' ]
Is that some kind of VSCode bug, or there is something about printing arrays with console.log() (with strings and integers it works just fine) what I don't take into account?
One solution you could try is to convert the array to a string when doing the console.log command:
let fruits = [['Apple', 'Banana'],['Apple', 'Banana']];
console.log(fruits.toString()); // Apple,Banana,Apple,Banana
console.log('' + fruits); // Apple,Banana,Apple,Banana
console.log(JSON.stringify(fruits)); // [["Apple","Banana"],["Apple","Banana"]]
I like the last one because it keeps this array displayed within brackets, even with multidimensional arrays.
However, one problem I found with this is when working with regular expression, there is addition output lost when converting to a string:
let str = 'xyz';
let pat = /y/;
let res = str.match(pat);
console.log(res); // ['y', index: 1, input: 'xyz', groups: undefined]
console.log(res.toString()); // y
console.log('' + res); // y
console.log(JSON.stringify(res)); // ["y"]
I believe this error may be occurring because the debugger is stopping before the output is sent to the debug console? Therefore For another solution, either add an empty line at the end of your code and add a breakpoint there; this seems to allow all the output to be generated when doing a multiple console.logs on arrays. Or, at the end of the code, add:
setTimeout(() => { }, 1000)
Which also seems to be adding enough time to properly output all the console.log of arrays. The advantage to the former is, you can expand the array details in the debug console, until you continue to the end of the code, but the con is you still have to chose to continue the code for it to end. The latter also allows you to expand the details of the object in the output, but only for the duration of the timer.
I also found, you can add either of these to your launch.json file (within the appropriate node configuration object, and don't forget to add a common to either the end the line before and/or the the end of either of these lines depending on where you are inserting):
"console": "integratedTerminal"
Or:
"console": "externalTerminal"
These send the output to either the VS Code terminal pane or an external cmd window.
And finally I also found instead of either of these console command, you can add this to the launch.json:
"outputCapture": "std"
This will keep the output in the debug console. It looks a bit different with color & some other messages, but seems to successfully output arrays.
I have the same problem. I think it is some kind of VSCode bug.
When I print the data in a event callback, console.log behave as expected. But after a while, the main thread exists and console.log output Canceled.
import some modules...
vtgeojson(tiles, { tilesOnly: true })
.on('data', function (data) {
featurecollection.features.push(data);
console.log(data)
})
.on('end', function () {
console.log(featurecollection);
console.log(featurecollection.features.length);
})
The problem disappears when I set the breakpoint and print the data line by line.
The problem also disappears when I run the script in the powershell.
Although the console.log is canceled, the data has been successfully pushed into the feature list. The behavior is most likely caused by the vscode terminal or the way that vscode handle the console.log command.
My node version is v12.20.0 and VSCode version is:
Version: 1.51.1 (system setup)
Commit: e5a624b788d92b8d34d1392e4c4d9789406efe8f
Date: 2020-11-10T23:34:32.027Z
Electron: 9.3.3
Chrome: 83.0.4103.122
Node.js: 12.14.1
V8: 8.3.110.13-electron.0
OS: Windows_NT x64 10.0.17763
I find someone else has a similar problem.
console.log() is “Canceled” when looping unattended
This seems quite interesting. I have tried running it multiple times and got the same result as output from Chrome's console:
["Apple", "Banana"]
["Apple1", "Banana1"]
The issue could be related either to the version of Node.js you are running on your computer or the terminal on the version of VSCode you have.
Because I tried running it from the VSCode terminal and got the same result:

spawn a command line operation in nodejs without opening console

I need to execute a command line operation from nodejs program. But I don't want to open console. I need to get result back to a variable. sync-exec module is helping to get result back but it keeps open a console for process execution.
I am sharing small bit of code.
var execSync = require('sync-exec');
var npmGlobalPath = execSync('npm config get prefix');
console.log(npmGlobalPath);
one more thing I want to share. This was happening when I already spawned a child process from parent. Now this code is in child process.

Get a unique re-useable identifier of node (cli-)app what is running in different terminal windows in parallel by same user?

I like to get an unique reusable identifier of the terminal window my node app (a CLI) is running in. The reason I like to know this is the common use of the app by the same user within multiple terminals at the same time.
It is necessary to get back selected data for each terminal and also getting to know what is selected on different terminal windows the CLI-App is running in.
The best way to save this would be in a hidden log file basically named by a unique terminal identifier.
[x] Working on process.platform === 'win32' each cmd.exe has its own PID.
[ ] Working on process.platform === 'darwin' (Mac OS X) the PPID is the same on all terminal windows.
[ ] Working on process.platform === 'freebsd' || 'linux' || 'sunos' I assume it is the same problem also depending on the GUI you are running.
Executing tty on the terminal gives me different identifiers like /dev/ttys003 what would be useful.
But trying to get this out of the app is not possible because executing this within a child_process ends up in a not a tty!
The PID of the app itself is changing every time it is executed. Thats not helpful in this case. The parent PID is the same (but also in different terminals).
Setting env will not be bound to the terminal but only to the apps runtime.
Is there any idea to get this done ?
I got it myself:
SpoTTY is the solution for posix based systems.
The example on the page has a misleading bug - use this example to get it done:
// A clone of the `tty` command
var spotty = require('spotty');
var tty = spotty.tty(function(err, res) {
if (err) {
console.error("Error found: " + err.toString())
} else {
return res;
}
})
hope this helps someone.

Inconsistently getting Error: [$injector:modulerr] Failed to instantiate module

I'm getting inconsistent results from Angular/Karma/Jasmine. When I run 'npm test', I get:
INFO [karma]: Karma v0.10.10 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
INFO [Chrome 35.0.1916 (Linux)]: Connected on socket aW0Inld7aRhONC2vo04k
Chrome 35.0.1916 (Linux): Executed 1 of 1 SUCCESS (0.345 secs / 0.016 secs)
Then, if I just save the code or test file (no changes), it will sometimes have the same results, sometimes it gives errors:
INFO [watcher]: Removed file "/home/www/raffler/entries.js".
Chrome 35.0.1916 (Linux) Raffler controllers RafflerCtrl should start with an empty masterList FAILED
Error: [$injector:modulerr] Failed to instantiate module raffler due to:
Error: [$injector:nomod] Module 'raffler' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
This is WITHOUT MAKING CHANGES. If I stop Karma and restart it works again, but once it fails it always fails. What gives? Buggy Angular/Jasmine/Karma? The code and test are trivial. Here is the code:
var myApp = angular.module('raffler', []);
myApp.controller('RafflerCtrl', function($scope, $log) {
$scope.$log = $log;
$scope.masterList = [];
});
And here is the test:
'use strict';
describe('Raffler controllers', function() {
describe('RafflerCtrl', function(){
var scope, ctrl;
beforeEach(module('raffler'));
beforeEach(inject(function($controller) {
scope = {};
ctrl = $controller('RafflerCtrl', {$scope:scope});
}));
it('should start with an empty masterList', function() {
expect(scope.masterList.length).toBe(0);
});
});
});
Am I doing something dumb? Seems like it should give me consistent results, regardless of my stupidity level... Thanks.
You were asking if there was a bug. There is. The authors of Karma know that there are problems with file watching. See this issue: https://github.com/karma-runner/karma/issues/974
Simply saving the file without changes can trigger this behavior. There's two main ways that files get saved. The first is to delete the original (or rename it to .bak or something) and then write out the new content. The second method writes the new content to a temporary file, deletes the original and then moves the temporary file to where the original used to be. For both of those the file system monitoring can fire an event saying that some files/directories changed. Node is quick enough to be able to detect the file was removed and tells Karma to stop using it in its tests. A slightly less used third way is to open the file in a special way to overwrite the contents, which will keep Karma happy.
Back to that bug ... in the above scenario, the globs are not re-evaluated when file system changes are detected. So it thinks your file was removed. It never saw that a new file was added, thus it's now out of the test suite.
This bug is bothering me too. If you've got an idea or a pull request then I'd suggest providing it to the Karma team. There's already a patch being reviewed that should address these problems - see https://github.com/karma-runner/karma/issues/1123.
As a workaround, you can use "set backupcopy=yes" for vim. There may be settings in other editors to change the behavior so that the file is overwritten instead of replaced.

Resources