Sometimes some (non critical) errors come out during the executing of my Javascript code.
While I'm aware that a workaround is not the best solution, I'm stuck on a blocking error which I need to get rid of.
Since the error is basically can't read [0] of undefined (the array doesn't exist), what I'd like to is something like:
try{
var abc = array[0];
} catch(e){
// continue execution
// skip to the end of this function
// run a different a function [e.g. alternativeFunction()]
// ignore the error
}
the try...catch block works, it prints the error but my Javascript code is being blocked.
Related
I'm writing a unit test framework. I noticed Mocha purports to handle exceptions in your test code gracefully, mapping the exception to the correct test in the log output. I'm attempting to do the same thing here. Let's ignore mapping the exception to the correct test for now (I'll def take a suggestion though, I'm stumped on how I'll do that for now)
I add all the test functions into the testmap, iterate over the keys in the testmap, and call each test's function one by one. I stall till the tests report back completed. I wrap around this a try-catch block to catch any exceptions that happen in any of the tests. It works - I can catch exceptions generated in the tests but even though I catch them, the program terminates. I do not want the program to terminate, and I don't think it's supposed to if you catch the exception... what gives?
Here is the try-catch in my library code
this.runtests = () => {
try {
Object.keys(this.testmap).forEach((test) => {
performance.mark(test)
this.testmap[test].testfunc();
});
this.stalltillgood(() => {
this.finallog();
});
}
catch (e) {
console.log('UNHANDLED EXCEPTION IN TEST');
console.log(e.stack);
}
};
Here is the client code which generates the exception - it is ENOENT - no such file or directory - hello.htm doesn't exist (on purpose)
expected('<fuck>&<fuck>');
testinfo('A Hello World Test', //the name of the test [MUST PASS TO ACTUAL AS WELL]
'This is the hello world test doc lol'); //the doc
comparator(cmp.equals); //you can use the pre built compare functions or your own
test(() => { //pass your test function to test
const file = fs.readFileSync('./hello.htm');
actual('A Hello World Test', file.toString());//make a call to actual in your test code
}); //to pass it your test result
//write more tests with the same sequence of commands
I think my problem is that this.runtests is the last method called, and after continuing on from my catch block, the program literally never has anything to output to me again, everything should be logged by then. The program just terminates after the catch block. I think I will have an extra var in test 'started' and just restart this.runtests, which will now check to see if a test has been started before trying to start it! Hooray! Still don't know how to map the exception to the proper test, maybe e.stack? Actually yeah that should be easy I guess lol.
I think my problem is that this.runtests is the last method called, and after continuing on from my catch block, the program literally never has anything to output to me again, everything should be logged by then. The program just terminates after the catch block. I think I will have an extra var in test 'started' and just restart this.runtests, which will now check to see if a test has been started before trying to start it! Hooray! Still don't know how to map the exception to the proper test, maybe e.stack? Actually yeah that should be easy I guess lol.
Why won't a JavaScript function run if there is an error in another function?
I ran this html page and tried to load the alert from the popup1() function, but it wouldn't work because there is an error in the if statement of the popup2() function:
<html>
<body>
<button onclick="popup1()"> Pop up 1 </button>
<button onclick="popup2()"> Pop up 2 </button>
<script>
function popup1()
{
alert ("Pop up 1");
}
function popup2()
{
if ( 1 = 1)
{
alert ("Pop up 2");
}
}
</script>
</body>
</html>
When I corrected the if statement to if (1 == 1), both functions worked.
Why did this affect the other function?
Is there any free software you can recommend that will find syntax errors in JavaScript for me, I really don't want to trawl through code again because of a missing equal sign. I tried eclipse for php but it didn't manage to find this.
Javascript runs in blocking sequence, so if there is any error anywhere it will stop execution.
(this is assuming you have no asynchronous function callbacks that started before the error happened)
The line of code if ( 1 = 1) is a parse error in Javascript. When your code fails to parse properly, the Javascript parser stops parsing your code immediately and that script is considered to have a fatal error and is not loaded.
At that point, it has found illegal Javascript and at best the parser has decided this is a fatal error and at worst, the parser is hopelessly confused about what your code would have meant and cannot proceed. In any case, this is how the Javascript parser works. It stops on the first parse error it encounters within any given script.
Your specific error would have been shown to you in the Javascript console as soon as you loaded that page. Your FIRST line of defense should be to keep your eye on the debug console. You should watch it regular, but ALWAYS look there whenever anything is not working as you expect.
In Chrome, it would have told you:
Uncaught ReferenceError: Invalid left-hand side in assignment
In addition, you can run various "lint" type programs on your code and it will advise you not only about errors, but also about dangerous practices. Personally, I use http://jshint.com/, but there are several different programs that offer this capability.
this error is because a number can not be redeclare, since a number always going to be the same number.
This causes a syntax error and affects the rest of the code. if you try to make this example work without problems.
function popup2()
{
var number = 1;
if ( number = 1)
{
alert ("Pop up 2");
}
}
I'm having to make a Javascript API that is the public interface to a C-based API that has enumerations and required parameters. Javascript, being a loosely typed language, wouldn't offer the same kind of compiler warnings one might get when using a C-based API.
My question is when making a Javascript wrapper around the C API, is it expected in the Javascript culture that one would receive a TypeError when passing invalid data or would it be more expected for the API to output a message to the console and ignore the error?
Here's some sample code for the API...
var Foo = (function() {
var foo = {
Enum: {
First: {value: 0},
Second: {value: 1},
Third: {value: 2}
},
bar: function(eenoom, aNumber) {
if (!eenoom) {
throw new TypeError("bar: You must specify the 'eenoom' parameter");
return;
}
if (!aNumber || typeof aNumber != 'number') {
throw new TypeError("bar: You must specify the 'aNumber' parameter (as a number)");
return;
}
for (var key in foo.Enum) {
if (foo.Enum.hasOwnProperty(key)) {
if (foo.Enum[key] === eenoom) {
console.log("You did it!");
return;
}
}
}
throw new TypeError("bar: You must use the Foo.Enum enumeration");
}
}
// So no one can mess with our enums
Object.freeze(foo.Enum);
return foo;
})();
Foo.bar(Foo.Enum.First, 20);
Foo.bar({value: 0}, 20); // Throws a TypeError
Note the use of TypeError. Is this an expected way for a Javascript API to behave?
I mainly do the following:
In synchronous public APIs I always check parameters and throw the appropriate error. Not only TypeError but also other errors as appropriate.
Generally I throw errors in exceptional cases - i.e. not fitting the thought-out execution flow.
In asynchronous APIs I report errors via an error callback/reject function.
I think console.log(...) and go on is not a good idea. If the call did not met the pre-conditions of the API, the API contract is broken from the very start. (Unless the contract is, specifically "yes, I can handle bad input" which is quite decadent.)
In this case nothing that you do afterwards will be correct. So throw an error and break off.
As an API consumer I'd be grateful for a thrown error with a good stack trace and a meaningful error message - much more that for just a meaningfull error message in the console (which I may or may not notice).
If the programmer has written code that will never work (not provided required parameters, sent the wrong type or order of parameters, etc...), then you want the code to fail immediately, fail visibly, clearly tell the programmer what is wrong and provide a stack trace that shows exactly where the offending code is.
The cleanest way to do that in Javascript is by throwing an appropriate type of error with a meaningful description. The very first time this code is executed, it will fail and the developer will immediately know they have done something wrong. This is what you want. Anything else increases the chances that the developer does not immediately realize the programming mistake they've made or even if they realize something isn't working, it might take them significantly longer to figure out why it isn't working.
A console.log() statement has these drawbacks:
It may not be seen immediately or at all.
It doesn't provide a stack trace so it may not be obvious what specific part of the caller's code is causing the error.
Since the app may not fail noticeably, it may appear that nothing is wrong or nothing serious is wrong when in reality there is a major programming mistake that must be fixed.
What is the difference between these two statements, and is there a good reason to use one over the other?
throw Error("msg");
console.error("msg");
In my limited experience, I've only really seen throw Error() used. Is there any particular reason why?
Also, is there an equivalent to console.warn() in the same fashion?
throw ... raises an exception in the current code block and causes it to exit, or to flow to next catch statement if raised in a try block.
console.error just prints out a red message to the browser developer tools javascript console and does not cause any changes of the execution flow.
Some of the Differences are:
throw Error("msg"):
Stops js execution.
Mostly used for code handling purpose.
Can alter main flow of execution.
This syntax is mostly same for all browser as this is specified and validated by W3C.
console.error("msg"):
It just shows output in Red color at Browser console
It is mostly used to print values for debugging purpose.
Cannot harm main flow of execution.
This Syntax sometimes vary according to vendor browser and not standardized by W3C.
i.e. For IE accepted syntax is window.console.debug("msg")
Throw is for actually changing the control flow (jumping out of the current context and up to an error handler) for handling errors programmatically. The console statement is just for debugging and printing text to the error console. You may see them used in conjunction, for example:
var doSomethingDangerous = function(response) {
if (isMalformed(response)) {
throw Error('Response is malformed.');
}
process(response);
};
var sendAsyncRequest = function() {
var request = buildAsyncRequest();
request.sendThen(function (response) {
try {
doSomethingDangerous(response);
} catch (e) {
console.error(e);
doSomeAdditionalErrorHandling();
}
});
};
I'm trying to access a file, that might not exist:
var localFolder = Windows.Storage.ApplicationData.current.localFolder;
localFolder.getFileAsync(stateFile).then(function (file) {
Windows.Storage.FileIO.readTextAsync(file).then(function (text) {
// do something with the text
});
}, function (err) {
// log error, load dummy data
});
if the file is not there, the "fail" method does get called, BUT it happens only AFTER my application halts with an exception "file not found". only when I press "continue" for the debugger does it continue to the "fail" method..
what am i doing wrong? should i check for existence beforehand?
You're seeing a first-chance exception. The debugger is breaking at the point of throw. If you hit the "continue" button on the debugger dialog, the app will keep running and the exception handler will run.
You can change this by using the "Debug|Exceptions" menu to turn off first chance exceptions.
I have been struggling with this same problem for two or three days and finally came to the following solution: I use getFilesAsync function to get the list of all files in a folder, and then look through this list to know if the needed file exists. After that I can call getFileAsyns without throwing. Not very pretty, but works for me. I agree that assuming that a developer can turn exceptions off is not the best advice... In my opinion this issue should be considered as a bug in RT implementation.