Any suggestion as to why the following implementation works, but is considered a jshint error?
try {
map.childNodes.length;
} catch (err) {
console.log(err);
}
I just want to see if childNodes has a length before iterating.
Similar thing here:
try {
response.errors.length > 0;
deferred.reject(response);
} catch (e) {
deferred.resolve(response);
}
The warning from JSHint is:
Expected an assignment or function call and instead saw an expression.
The warning shows up even without the use of a try..catch. JSHint is letting you know that map.childNodes.length; as a standalone statement probably isn't useful, and is likely indicative of a coding mistake; i.e., in most cases, you want to do something with the value, not just access it as a standalone statement. For example, you get the same warning with the (useless) statement 5;.
Of course, sometimes it might be useful to access a property as the only behavior in a statement. For example, if you have a getter function defined on the property with Object.defineProperty, then accessing the property will trigger the getter function. However, it's vastly more likely that a value-only statement is coding error, so JSHint warns you about the suspicious code.
That said, your approach could be improved, assuming you're worried that response.error might be a falsey value (undefined, null) instead of an object:
if(response.errors && response.errors.length > 0) {
deferred.resolve(response);
} else {
deferred.reject(response);
}
Because you're abusing conditional operators that ought to be in if conditions. JSHint isn't meant to be approving of anything you can do in Javascript.
For the first, you could use an Array type check, such as:
if (toString.call(map.childNodes) === '[object Array]') {
//iterator
}
For the second, something like this perhaps:
if (response.errors && response.errors.length > 0) {
deferred.reject(response);
} else {
deferred.resolve(response);
}
Related
I have the following function in my react js as follows which is fairly simple and returns different values based on conditions.
const checkStatus =(device:any)=> {
if(device?.patient){
return "disconnect"
} else if(!device.patient && device?.status === "DEACTIVATED") {
return "delete"
}
else {
return "enable"
}
}
above code throws and error "Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." . can anyone help me understand what is wrong here
You are using the ternary operator in a weird way which could cause the js to not function as intended. Try removing it(note that your code may run differently than intended).
const checkStatus = (device:any) => {
if (device.patient) {
return "disconnect";
} else if (!device.patient && device.status === "DEACTIVATED") {
return "delete";
} else {
return "enable";
}
}
It is not very clear from the question where this function is called. But some problems can be spotted which should lead to errors. Seems what is happening is that function is called in a react component, and its throwing an exception which causes the react component not to reach the return statement of its render thus throwing the exception: "Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null."
3 problems can be seen in this function:
1- you are not checking if the argument device if null. If it is null device.patient will throw an exception.
2- you are using ternary operator in a weird way. If its to satisfy ts linting, its wrong. This can be avoided by adding a guard clause at the start of the function: if (!device) return null;. ts will analyze the control flow and it won't require you to add the ternary operator.
3- if any is used with typescript there is something wrong with the function. Why it should expect any argument ? Why not an object that have patient and status as members ?
I ran into a bug which I finally solved, but why it happen(ed/s) is still beyond me.
I save a variable foo using browser.storage.local.set for a firefox addon that I'm developing. I know that the variable is set, and the apparent bug was relying on some small piece of code that leads to this:
browser.storage.local.get((val) => {
if (val['foo'] === undefined){
console.log('Undefined');
}
else {
console.log('Defined')
}
});
// Outputs `Defined`, which is correct.
However, if I define the callback first, and then I get wrong output.
function checkStoredSettings(val) {
if (val['foo'] === undefined) {
console.log('Undefined')
}
else {
console.log("Defined")
}
}
browser.storage.local.get().then(checkStoredSettings, console.log);
// Outputs `Undefined`, which is incorrect.
//UPDATE
browser.storage.local.get(checkStoredSettings);
// Outputs `Undefined`, which is also incorrect.
Can someone explain what am I not getting here? I have now run the above two codes sequentially (in both orders) in the same scope.
Did you tried something like that ?
browser.storage.local.get('foo').then(console.log)
The Problem:
Recently, while reviewing our existing test codebase, I've noticed a dangerous kind of typo/mistake when expect() was used without the "matching" part:
expect(page.filters.fromDateLabel.getText(), "After");
I'm pretty sure toEqual() was meant to be used here:
expect(page.filters.fromDateLabel.getText()).toEqual("After");
The problem with this is that jasmine would not fail the expectation in this case (well, obviously because nothing was actually expected). And this gets us to a more serious problem - nothing was actually tested in a test case - it was passing with no expectations made. We were getting a false sense of what was tested.
The Question:
I want to catch these mistakes as fast as possible. How do you think I should handle the problem?
Thoughts:
somehow fail a test case if there was no expectations made in it (not sure if jasmine has anything like this built-in)
"patch" the expect() and issue a warning/raise an error if nothing was called on the "expect" part
use static code analysis - define a custom eslint rule
The custom ESLint rule provided in the answer is now a part of eslint-plugin-jasmine 1.6.0:
valid-expect
Old Answer:
Here is a custom ESLint rule I've ended up with:
module.exports = function (context) {
return {
// checking "expect()" arguments
CallExpression: function (node) {
if (node.callee.name === 'expect') {
if (node.arguments.length > 1) {
context.report(node, 'More than one argument passed to expect()')
} else if (node.arguments.length === 0) {
context.report(node, 'No arguments passed to expect()')
}
}
},
// nothing called on "expect()"
'CallExpression:exit': function (node) {
if (node.callee.name === 'expect' && node.parent.type === 'ExpressionStatement') {
context.report(node, 'Nothing called on expect()')
}
}
}
}
It checks for 3 things:
more than 1 argument passed to expect()
no arguments are passed to expect()
there was nothing called on expect()
Here are the sample invalid expect() usages it currently catches:
expect(page.filters.fromDateLabel.getText(), "After");
expect("After");
expect();
As for the option #1, there is actually a quite related and useful ESLint rule being already implemented and open-sourced by [eslint-plugin-jasmine]:
Enforce expectation (missing-expect)
I tend to think that the static analysis route is best, but if you’re looking for a quick and dirty way, here’s some code that grabs the expectations returned by all calls to expect and creates a proxy that tracks whether any of the expectation’s properties were ever used:
var unusedExpectations = new Set();
var originalExpect = window.expect; // Should be empty after every spec
var expect = function() {
var rawExpectation = originalExpect.apply(this, arguments);
unusedExpectations.add(rawExpectation); // Assume unused until used
// Traverse expectation and its prototypes, copying all properties to
// our proxy object. (Note that this becomes much simpler if you have
// ES6 Proxy in your environment.)
var proxy = {}
for(var proto = rawExpectation; proto; proto = proto.__proto__) {
Object.getOwnPropertyNames(proto).forEach(function(prop) {
if(Object.getOwnPropertyDescriptor(proxy, prop))
return;
Object.defineProperty(
proxy, prop, {
get: function() {
// Aha! Somebody used this expectation for _something_.
unusedExpectations.delete(rawExpectation);
return rawExpectation[prop];
}
}
);
});
}
return proxy;
}
Put that in a place where it hides Jasmine’s expect from your specs, and then:
beforeEach(function() {
unusedExpectations.clear();
});
afterEach(function() {
expect(unusedExpectations.size).toEqual(0);
});
Caveats:
Kind of evil.
Will not catch expect(foo).toBeFalsy; (missing parens).
Counts the use of any property, so won’t catch expect(foo).toString().
Still, it works!
One could add code to inspect the stack trace and extract the location of the offending expect(), but I imagine flagging which spec has an unused expect() is sufficient.
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.
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
}