Check if file exists before using require in NodeJs [duplicate] - javascript

I need to check if file/(custom)module js exists under some path. I tried like
var m = require('/home/test_node_project/per');
but it throws error when there is no per.js in path.
I thought to check with
fs if file exists but I don't want to add '.js' as suffix if is possible to check without that.
How to check in node if module exists and if exists to load ?

Require is a synchronous operation so you can just wrap it in a try/catch.
try {
var m = require('/home/test_node_project/per');
// do stuff
} catch (ex) {
handleErr(ex);
}

You can just try to load it and then catch the exception it generates if it fails to load:
try {
var foo = require("foo");
}
catch (e) {
if (e instanceof Error && e.code === "MODULE_NOT_FOUND")
console.log("Can't load foo!");
else
throw e;
}
You should examine the exception you get just in case it is not merely a loading problem but something else going on. Avoid false positives and all that.

It is possible to check if the module is present, without actually loading it:
function moduleIsAvailable (path) {
try {
require.resolve(path);
return true;
} catch (e) {
return false;
}
}
Documentation:
require.resolve(request[, options])
Use the internal require() machinery to look up the location of a module, but rather than loading the module, just return the resolved filename.
Note: Runtime checks like this will work for Node apps, but they won't work for bundlers like browserify, WebPack, and React Native.

You can just check is a folder exists by using methods:
var fs = require('fs');
if (fs.existsSync(path)) {
// Do something
}
// Or
fs.exists(path, function(exists) {
if (exists) {
// Do something
}
});

Related

How to know whether a piece of JS is executed in an ES Module or a regular script?

I want to know whether a piece of JavaScript is executed in an ES module or a simple script.
This is what I tried so far:
function isEsm1() {
try {
// Script gives a syntax error during parsing when script is not an esm
return Boolean(import.meta.url);
} catch(err) {
return false;
}
}
function isEsm2() {
// will always return false, because `eval` always seems to be executed in regular script context
try {
return eval('Boolean(import.meta.url)');
} catch(err) {
return false;
}
}
function isEsm3() {
// Of course doesn't work, but had to try 😉
return 'meta' in import;
}
Is the regular script executed in the browser or in another context?
In a browser, how about:
var anyvar = {};
var inModule = anyvar === window.anyvar;
If you're in a module, you are not declaring anything on the window...
In NodeJS you could do something similar with global or this:
let inModule = this === module.exports..
Did not try it yet.. but should work I guess...
After testing, just the check for this === undefined is enough to test if you're executing in or out of a module..
Inside a module, this is undefined (as per spec). In global scope this points to global this, which is the window object in the case of a browser context...
Thanks to the discussion in John Gorter's answer, I think we've found a way.
console.log('In module: ' + (this === undefined));
It's as simple as that. Inside a module (and only inside a module (I hope)), this will be undefined. I found it in the v8 documentation here: https://v8.dev/features/modules#intro

javascript try catch vs if then else

I need to be able to run a bunch of code if a statement is successful. If javascript had a try/catch/else then I would put all the code in the else and be done with it. I don't want to use a Boolean to mimic the else in try/catch/else. My understanding is that try can handle an error but can't IF do the same? If so, I'll have to use the IF but I don't want my program to crash if the QueryInterface fails. So my question is, if the QueryInterface fails, then the else will be executed in the IF below correct? If so then I guess the only reason to use a try/catch is to snag the error condition.
existing method:
try {
channel = subject.QueryInterface(Ci.nsIHttpChannel);
} catch(err) {
booSuccess = false;
intErrorCount++
}
if (booSuccess == true) {
...bunch of stuff...
}
proposed method:
if (channel = subject.QueryInterface(Ci.nsIHttpChannel)) {
...bunch of stuff...
} else {
intErrorCount++
}
No, throwing an exception (which you catch with the first snippet) is very different from returning an error code (channel == 0, which the second snippet checks). They do not do the same.
What you might do to avoid that boolean variable is
try {
channel = subject.QueryInterface(Ci.nsIHttpChannel);
...bunch of stuff...
} catch(err) {
intErrorCount++
}
but that would also raise the error count if an exception happens in the bunch of stuff.
No you can't simply replace the try/catch with an if/else. If a line throws an error, the javascript interpreter will stop execution of that script.

Dynamically loading js script from bookmarklet

I'm trying to load a script so I can use scripts on the page that is spawned by the bookmarklet. (view src: XHR followed by beautify.js followed by prettify.js)
I know what I am basically supposed to do (like this) but what's happening is I can't find a good way to detect when the functions I need are actually loaded.
var doWhenLoaded = function (name) {
if (typeof(eval(name)) === 'function') {
eval(name+'()');
} else {
setTimeout(
function () {
console.log("from timeout: "+new Date().getTime());
doWhenLoaded(name,call);
} , 50
);
}
}
I tried that but eval(name+'()'); throws an error.
I can't answer your question, but to test if a function is available use:
var doWhenLoaded = function (name) {
if (typeof window[name] == 'function') {
window[name]();
} else {
// set the timeout. Should have a limit, else it wil go on forever.
}
...
};
Edit
Updated to use window[name], but really should use a reference to the global object. But I guess it's ok to use window for a browser specific script.
The code above should not throw any errors. Since name is in the formal parameters, it's essentially a declared local variable. If name is undefined, then typeof name will return the string "undefined", which fails the test so name() is not evaluated.
I think I can force the scripts to get loaded synchronously before I end up calling them by simply writing the document rather than setting them into the dom.

Catching module loading errors and processing them

I am trying to load some content using require.js. If the content doesn't exist I'd like to catch the error and notify the user.
In firebug I can see two errors:
"NetworkError: 404 Not Found
...and then a few seconds later:
var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#
Load timeout for modules: modules/messages/messages
http://requirejs.org/docs/errors.html#timeout
My code resembles:
require([path], function(content){
//need to catch errors as this will not be called;
});
How would one bind to requirejs events? Any idea?
It is also possible to use errbacks to have customized error handling appropriate to the specific use of require. Errbacks are documented here http://requirejs.org/docs/api.html#errbacks. Basically, you can add to require a function to be called if the load fails. It comes right after the function to be called if the load is successful.
Chin's case could be handled as:
require([path], function(content){
//need to catch errors as this will not be called;
}, function (err) {
//display error to user
});
Here's an example that tries loading from multiple places:
require([mode_path], onload, function (err) {
if (mode_path.indexOf("/") !== -1)
// It is an actual path so don't try any further loading
throw new Error("can't load mode " + mode_path);
var path = "./modes/" + mode_path + "/" + mode_path;
require([path], onload,
function (err) {
require([path + "_mode"], onload);
});
});
In this example onload would be the function called once the required code loads, and mode_path is a string identifying the mode. What you see there is code attempting to load a mode module for an editor from 3 different locations. If mode_path is foo, it will try to load foo, then ./modes/foo/foo and then ./modes/foo/foo_mode.
The example at requirejs.org shows how one might handle a case where they want to try multiple locations for a resource they want to make available with a well-known identifier. Presumably the entire code-base in that example requires jQuery by requiring "jquery". Whatever location jQuery happens to be located at, it becomes available to the whole code-base as "jquery".
My example does not care about making the mode known to the entire code-base through a well-known identifier because in this specific case there's no good reason to do so. The onload function stores the module it gets into a variable and the rest of the code base gets it by calling a getMode() method.
set the requirejs onError function:
requirejs.onError = function (err) {
if (err.requireType === 'timeout') {
// tell user
alert("error: "+err);
} else {
throw err;
}
};
If you want to setup an event you could bind to and trigger a global object. Such as:
$("body").bind("moduleFail",function(){
alert("Handling Event")
});
requirejs.onError = function (err) {
if (err.requireType === 'timeout') {
$("body").trigger({type:"moduleFail",err:err})
} else {
throw err;
}
};
require(["foo"],function(foo){
alert("loaded foo" + foo)
})
Did you try to override the requirejs.onError like shown here?
It worked for me after setting catchError as true like this:
require.config({catchError:true});
before calling any define() or require() functions.
You can use the requirejs.onError function as :
requirejs.onError = function (err) {
if (err) {
//Reload
}
else {
throw err;
}
};
You can also use err.requireType to catch specific errors like timeouts

eval javascript, check for syntax error

I wanted to know if it is possible to find through javascript if a call to eval() has a syntax error or undefined variable, etc... so lets say I use eval for some arbitrary javascript is there a way to capture the error output of that eval?
You can test to see if an error is indeed a SyntaxError.
try {
eval(code);
} catch (e) {
if (e instanceof SyntaxError) {
alert(e.message);
}
}
When using try-catch for catching a particular type of error one should ensure that other types of exceptions are not suppressed. Otherwise if the evaluated code throws a different kind of exception it could disappear and cause unexpected behaviour of the code.
I would suggest writing code like this:
try {
eval(code);
} catch (e) {
if (e instanceof SyntaxError) {
alert(e.message);
} else {
throw e;
}
}
Please note the "else" section.
According to the Mozilla documentation for eval:
eval returns the value of the last expression evaluated.
So I think you may be out of luck. This same document also recommends against using eval:
eval() is a dangerous function, which executes the code it's passed with the privileges of the caller. If you run eval() with a string that could be affected by a malicious party, you may end up running malicious code on the user's machine with the permissions of your webpage / extension. More importantly, third party code can see the scope in which eval() was invoked, which can lead to possible attacks in ways of which the similar Function is not susceptible.
So regardless, please be aware of the risks before using this function.
You can use JsLint which contains a javascript parser written in javascript. It will give you lots of information about your code, it can be configured to be more relaxed or not, etc...
To continue using the code after validation, I use the following example:
var validCode = 1;
try {
eval( jsCode ); /* Code test */
} catch (e) {
if (e instanceof SyntaxError) {
validCode = 0;
console.warn(e.message);
}
} finally {
if(validCode){
"do some magic"
}
}
This Below code posted by go-oleg thanks to him
This code validate the correct syntax otherwise return error
Note:code is not vaildate run time error because it uses ast parser to analyze the correct syntax.
To Install
npm install esprima --save
code:
var esprima = require('esprima');
var userStringToTest = 'var a = 50;';
var isValid = isValidJs(userStringToTest);
if(isValid) {
alert('its validated!');
}
else {
console.log('its NOT valid syntax!');
}
function isValidJs(testString) {
var isValid = true;
try {
esprima.parse(testString);
}
catch(e) {
isValid = false;
}
return isValid;
}
put your desired value for b
//b="4+6";
try { eval(b); }
catch (err) {
if (err instanceof SyntaxError)
document.getElementById('screen').innerHTML = "<i>Syntax Error</i>";
/*In html make a div and put id "screen" in it for this to work
you can also replace this line with document.write or alert as per your wish*/
}
finally {
document.getElementById('screen').innerHTML = eval(b); //outputs answer
}

Categories