I am on a school Chromebook, where developer tools are disabled. I sometimes coded on node.js, having server-side and client-side code. But, as developer tools are disabled, I can't check errors on the client-side, as to only find that it sometimes just stops working without a clue as to what is wrong. I have had this issue a whole lot whenever coding client-side code.
How could I detect and identify the error with only access visually to the node.js console, as well as express and socket.io?
For example,
const express=require("express");
const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http);
app.use(
'/client',
express.static(__dirname + '/client')
);
app.get('/', (req, res) => {
res.sendFile(__dirname + '/client/index.html');
console.log("sending site");
});
http.listen(3000, () => {
console.log('listening on *:3000 (http.listen)');
});
io.on('connection', (socket) => {
socket.emit("ERRORNOW",26);
});
//"<script src="/socket.io/socket.io.js"></script>" assumed to be in HTML file
var socket=io();
socket.on("ERRORNOW",()=>{
if("this doesnt have an ending curlybracket){
//}
//this is the error it doesnt have the ending curly bracket,
//but it doesn't show in the node.js console
//(at least on browser IDEs like repl.it),
//and debugging without the developer tools
//can be infuriating to say the least
});
The question is How can I identify a node.js client-side error on a web-based IDE without developer tools?
I have already had this issue a while ago, and due to the lack of developer tools on school Chromebooks, found the solution on my own, but I just thought that maybe I should also put it here.
My solution, as simple as it may be, is to just use a try-catch statement and send the error to the node.js console. It took a while to figure that out...
So, if you don't already have it, you would need a function that when triggered from the client side can log something into the console, inside of the io.on("connection",()=>{}); thing, like so:
io.on("connection",()=>{
socket.on("log", input=>{
console.log(input);
});
});
For example, if everything runs off of a single function that is triggered really fast (specific, but relevant to me, as I make web games), or just off of something, you can run it off of a function inside a try catch, like so:
//"<script src="/socket.io/socket.io.js"></script>" assumed to be in HTML file
var socket=io();
try{
socket.on("ERRORNOW",()=>{
try{
if("this doesnt have an ending curlybracket){
//}
}catch(error){
socket.emit("log",error);
}
});
}catch(error){
socket.emit("log",error);
}
So now, with this simple solution, you can stop commenting out 90% of your code to find that one error that makes it stop working while breaking it further by accidentally commenting out parts that help it to work in the first place!
Related
I know you can use navigator onLine inside the renderer process because it's a rendered inside a browser. But what I'm trying to do is something like this in the main process:
if (navigator.onLine){
mainWindow.loadURL("https://google.com")
} else {
mainWindow.loadFile(path.join(__dirname, 'index.html'));
}
So basically if the user is offline, just load a local html file, and if they're online, take them to a webpage. But, like expected, I keep getting the error that 'navigator is not defined'. Does anyone know how can I somehow import the navigate cdn in the main process? Thanks!
TL;DR: The easiest thing to do is to just ask Electron. You can do this via the net module from within the Main Process:
const { net } = require ("electron");
const isInternetAvailable = () => return net.isOnline ();
// To check:
if (isInternetAvailable ()) { /* do something... */ }
See Electron's documentation on the method; specifically, this approach doesn't tell you whether your service is accessible via the internet, but rather that a service can be contacted (or not even this, as the documentation mentions links which would not involve any HTTP request at all).
However, this is not a reliable measurement and you might want to increase its hit rate by manuallly checking whether a certain connection can be made.
In order to check whether an internet connection is available, you'll have to make a connection yourself and see if it fails. This can be done from the Main Process using plain NodeJS:
// HTTP code basically from the NodeJS HTTP tutorial at
// https://nodejs.dev/learn/making-http-requests-with-nodejs/
const https = require('https');
const REMOTE_HOST = "google.com"; // Or your domain
const REMOTE_EP = "/"; // Or your endpoint
const REMOTE_PAGE = "https://" + REMOTE_HOST + REMOTE_EP;
function checkInternetAvailability () {
return new Promise ((resolve, reject) => {
const options = {
hostname: REMOTE_HOST,
port: 443,
path: REMOTE_EP,
method: 'GET',
};
// Try to fetch the given page
const req = https.request (options, res => {
// Yup, that worked. Tell the depending code.
resolve (true);
req.destroy (); // This is no longer needed.
});
req.on ('error', error => {
reject (error);
});
req.on ('timeout', () => {
// No, connection timed out.
resolve (false);
req.destroy ();
});
req.end ();
});
}
// ... Your window initialisation code ...
checkInternetAvailability ().then (
internetAvailable => {
if (internetAvailable) mainWindow.loadURL (REMOTE_PAGE);
else mainWindow.loadFile (path.join (__dirname, 'index.html'));
// Call any code needed to be executed after this here!
}
).catch (error => {
console.error ("Oops, couldn't initialise!", error);
app.quit (1);
});
Please note that this code here might not be the most desirable since it just "crashes" your app with exit code 1 if there is any error other than connection timeout.
This, however, makes your startup asynchronous, which means that you need to pay attention on the execution chain of your app startup. Also, startup may be really slow in case the timeout is reached, it may be worth considering NodeJS' http module documentation.
Also, it makes sense to actually try to retrieve the page you're wanting to load in the BrowserWindow (constant values REMOTE_HOST and REMOTE_EP), because that also gives you an indication whether your server is up or not, although that means that the page will be fetched twice (in the best case, when the connection test succeeds and when Electron loads the page into the window). However, that should not be that big of a problem, since no external assets (images, CSS, JS) will be loaded.
One last note: This is not a good metric of whether any internet connection is available, it just tells you whether your server answered within the timeout window. It might very well be that any other service works or that the connection just is very slow (i.e., expect false negatives). Should be "good enough" for your use-case though.
I'm trying to use a node.js app to regularly decode some gtfs-realtime data. It's mostly running fine, but every few hours I run into an error that crashes my app. The error message in my log says that there is an "Illegal group end indicator for Message .transit_realtime.FeedMessage 7 (not a group)"
I found this question/answer on StackOverflow but it doesn't seem to solve my particular problem. Here is an outline of the code I am using to decode the gtfs-r feed:
//process the response
var processBuffers = function(response) {
var data = [];
response.on('data', function (chunk) {
data.push(chunk);
});
response.on('end', function () {
data = Buffer.concat(data);
var decodedFeedMessage = transit.FeedMessage.decode(data);
allData = decodedFeedMessage.entity;
//continues processing with allData...
});
}
Thanks!
NodeJs crashed issue basically happen every time, everydays that any kind of fatal error trigger. And since your received data from 3-rd party, It will very had to make sure the data always correct to prevent error as well.
The simple solution is using another system to deploy your NodeJS application. I recommend 2 tools that very popular today, PM2 and Passenger . (PM2 is very simple to use). Those tool will help to auto restart your NodeJS application once it crashed
http://pm2.keymetrics.io/
https://www.phusionpassenger.com/library/walkthroughs/deploy/nodejs/ownserver/nginx/oss/install_passenger_main.html
I'm running a function which I've written in JavaScript inside a nodejs/Electron client.
This function is meant to copy a file from the users flash drive to their c:/Windows/System32 (The file is being copied there so that it can be ran from Command Prompt manually next time the computer is touched without having to switch directories)
The problem is, the files are not being copied, and copyFileSync is not throwing an error.
Here is the code I'm specifically having a problem with:
try {
console.log('copying t.bat');
fs.copyFileSync(remote.app.getAppPath() + '\\app\\files\\scripts\\files\\t.bat', 'C:\\Windows\\System32\\t.bat');
} catch(err) {
console.log('could not copy t.bat', err);
$('#mfail_title').text('Could not copy t.bat file');
$('#mfail_data').text(err);
UIkit.modal("#master_fail").show();
return false;
}
As you can see, I have copyFileSync inside a TRY CATCH block. I know this code is running because in the console I get copying t.bat, but nothing else.
How can I get my files to copy, or at least throw an error when it cannot?
This client is running inside OOBE mode on various Windows 10 machines, therefore always has administrator access.
I've tried updating to the async version of copyFile, but I'm having the same issue. Here is my code
var source = remote.app.getAppPath() + '\\app\\files\\scripts\\files\\t.bat';
var destination = 'C:\\Windows\\System32\\t.bat';
fs.copyFile(source, destination, (err) => {
if (err) {
console.log(err);
} else {
source = remote.app.getAppPath() + '\\app\\files\\scripts\\files\\p.bat';
destination = 'C:\\Windows\\System32\\p.bat';
fs.copyFile(source, destination, (err) => {
if (err) {
console.log(err);
} else {
source = remote.app.getAppPath() + '\\app\\files\\scripts\\files\\p.bat';
destination = 'C:\\Windows\\System32\\p.bat';
child = spawn("powershell.exe",['-ExecutionPolicy', 'ByPass', '-File', remote.app.getAppPath() + '\\app\\files\\scripts\\' + type + '.ps1']);
}
});
}
});
This should copy a file, then when it's complete it should copy another file, once that is complete, it should run a powershell script.
Each copyFile checks for an error before moving on, but it never throws an error, and the file is never copied.
I had a similar issue earlier, In which an Antivirus(Comodo) was not allowing electron app to access the hard drive.
Copy and other file operations were successful in that case as well, because electron in such case access the corresponding sandbox
Please check this is not the case with you.
You can actually access 'fs' in console from electron and check other things in the file system.
Looks to me as if you're using fs on then renderer process (client side) which will not work (assuming that your fs is the node.js fs module and (*)). Your first script seems to use jQuery (hints for renderer) and the second one uses remote in the first line.
fs can only (*) be used on the main process and you'll need to create an IRC channel and do something like:
ircRenderer.sendSync('copy-file-sync', {from: '/from/path', to: '/to/path'})
and, of course, implement the handler for that quickly invented 'copy-file' channel on the main process.
(*) Edit: I haven't played around a lot with nodeIntegration = true, so fs may or may not work on the renderer process with that flag set on the BrowserWindow. But the irc messaging should definitely work and if not, the problem is outside electron, probably related to file permissions.
I'm new to javascript and node js.
I've following code in my authentication.js file
I'm trying to get the intellisense working when I press client. ( and CTRL + space), I do not see anything.
How do I be able to see functions that are within auth.OAuth2 modules.
I remember in VS you can use /// reference paths. Not sure if that is the standard approach in ATOM as well. I looked over the internet and could not find any satisfactory answer.
How do people know what methods to use and what is their required signature without intellisense?
I'm literally crawling to make things work right now because of this. Do I have to read documentation for every modules/packages before I start using it? That'd take a lot of time.
Please also note that I have added all the packages like autocomplete, autocomplete-plus and so on for the intellisense to work magically but it doesn't. Intellisense does work but it displays everything else but not the functions of the modules I'm referring to in the example.
Any help/suggestion is much appreciated?
'use strict';
var config = require("../../config/config");
exports.verifyUser = function(req, res, next) {
var GoogleAuth = require('google-auth-library');
var auth = new GoogleAuth;
var client = new auth.OAuth2(config.clientID, config.clientSecret,config.callbackURL);
**client. //no intellisense**
// check header or url parameters or post parameters for token
var token = req.body.id_token || req.query.id_token || req.headers['id_token'];
if (token) {
client.verifyIdToken(
token,
config.clientID,
function (err) {
if (err) {
res.send("Un authorized");
} else {
next();
}
});
}
}
I've had great success using Visual Studio Code.
Its a lightweight IDE similar to Atom, its actually also built using Electron.
You can check out a tutorial about how to get things set up here.
https://blog.tallan.com/2017/03/02/synthetic-type-inference-in-javascript/
You need to add an intellesense plugin for the language you're using. Atom isn't really suited to noobs though, you should try out netbeans if you want a fully featured editor.
I am trying to run a casper test for an internal site. Its running on pre-production environment, the code so far is
var casper = require('casper').create({
verbose: true,
loglevel:"debug"
});
// listening to a custom event
casper.on('page.loaded', function() {
this.echo('The page title is ' + this.getTitle());
this.echo('value is: '+ this.getElementAttribute
('input[id="edit-capture-amount"]',
'value'));
});
casper.start('https://preprod.uk.systemtest.com', function() {
this.echo(this.getTitle());
this.capture('frontpage.png');
// emitting a custom event
this.emit('age.loaded.loaded');
});
casper.run();
as you can see its not much but my problem is the address is not reachable. The capture also shows a blank page. Not sure what i am doing wrong. I have checked the code with cnn and google urls, the title and screen capture works fine. Not sure how to make it work for an internal site.
I had the exact same problem. In my browser I could resolve the url, but capserjs could not. All I got was about::blank for a web page.
Adding the --ignore-ssl-errors=yes worked like a charm!
casperjs mytestjs //didn't work
capserjs --ignore-ssl-errors=yes mytestjs //worked perfect!
Just to be sure.
Can you reach preprod.uk.systemtest.com from the computer on which casper runs ? For example with a ping or wget.
Is there any proxy between your computer and the preprod server ? Or is your system configured to pass through a proxy that should not be used for the preprod server ?
The casper code seems to be ok.
I know this should be a comment but I don't have enough reputation to post a comment.
As far as CasperJs tests are run in localhost, for testing a custom domain/subdomain/host, some headers need to be defined.
I experienced some problems when passing only the HOST header, for instance, snapshots were not taken properly.
I added 2 more headers and now my tests run properly:
casper.on('started', function () {
var testHost = 'preprod.uk.systemtest.com';
this.page.customHeaders = {
'HOST': testHost,
'HTTP_HOST': testHost,
'SERVER_NAME': testHost
};
});
var testing_url: 'http://localhost:8000/app_test.php';
casper.start(_testing_url, function() {
this.echo('I am using symfony, so this should have to show the homepage for the domain: preprod.uk.systemtest.com');
this.echo('An the snapshot is also working');
this.capture('casper_capture.png');
}